Documentation

A profile is a program that runs on your machine, and HCL is expressive enough to make a very small file do a very large amount of work. Glazier puts two hard limits on a profile so that one from an unknown source cannot use all the memory or crash glaze. It also has one gap it cannot close, and I would rather tell you about it here than have you find it.

The limits

LimitValueApplies to
Nesting depth256 levelsBrackets, braces, parentheses and strings inside each other, in a profile or a --var-file.
Locals budget1 MiBAll locals together, counted as the bytes of each string plus one for each element.

Both checks run before Glazier starts tmux. A profile past a limit fails with exit code 3.

Nesting depth

Glazier counts the nesting of a file before it parses the file. A file that nests more than 256 levels deep is an error, “Nesting too deep”, and the diagnostic points at the token that crosses the line. The check applies to the profile and to each --var-file.

Locals budget

All locals together can hold at most 1 MiB. Glazier resolves the locals in order of dependency and adds the size of each value to a running total. The first local that takes the total past the limit gets the error, “Locals too large”, and the diagnostic names it. See Locals.

What is not limited

warning

Read a profile from an unknown source before you run glaze on it. A large nested for expression is not limited. Such an expression can take a long time or use a lot of memory, and Glazier cannot stop it.

HCL gives Glazier no hook to count the steps of an evaluation, so a for expression nested inside another for expression can multiply its work without any limit that Glazier can enforce. The two limits above make a crash and a memory bomb through nesting or locals impossible. They do not make a slow expression impossible.

Why these two?

The nesting limit exists because the HCL parser recurses once per level of nesting, and around a hundred thousand levels overflow the Go stack. That is a fatal error that no recovery can catch: the process just dies. Counting the depth up front with the lexer, which does not recurse, costs almost nothing and makes the crash impossible. Nobody writes a profile 256 levels deep by accident ( or on purpose, I hope ).

The locals budget exists because locals is the one place where a value can feed on itself. A local that joins two copies of the one before it doubles every line, and a dozen lines later you are holding a gigabyte of string. One megabyte is far more than any honest profile needs and far less than it takes to hurt.

The for gap stays open because closing it would mean forking the HCL evaluator, and the fix for “I ran a file I had not read” is still “read the file”. See Security for the rest of the threat model.