summaryrefslogtreecommitdiffhomepage
AgeCommit message (Collapse)Author
2020-11-30syntax: recognize single-char escapes in regex literals againJo-Philipp Wich
Ensure that the single char escapes `\a`, `\b`, `\e`, `\f`, `\n`, `\r`, `\t` and `\v` keep working. Since they're not part of the POSIX extended regular expression spec, they're not handled by the RE engine so we need to substitute them by their actual byte value while parsing the literal. Fixes: ac5cb87 ("syntax: fix string and regex literal parsing quirks") Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-30syntax: fix string and regex literal parsing quirksJo-Philipp Wich
- Do not interprete escape sequences in regexp literals - Do not improperly substitute control escape sequences such as `\n` or `\a` after a backslash Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-30tests: fix testcasesJo-Philipp Wich
Fixes: 8b4d0d5 ("tests: prefer `let` over `local`") Fixes: a162cf7 ("treewide: rebrand to ucode") Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-19tests: prefer `let` over `local`Jo-Philipp Wich
Promote the use of `let` to move ucode examples closer to ES syntax. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-19treewide: rebrand to ucodeJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-16lib: optimize length() for objectsJo-Philipp Wich
Instead of counting the keys individually, use the existing json_object_object_length() function. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-16lib: extend length() to handle objectsJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-16lib: extend ord() to allow reading byte values at arbitrary indexesJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-16README.md: fix typosJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-16lib: add system() functionJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-15fs: extend process close() function to return program exit codeJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-15lexer: improve scanner performanceJo-Philipp Wich
Optimize the strncmp() based token lookup with an integer comparison approach which roughly cuts the time of the source code parsing phase in half. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-12parser: reuse T_FUNC nodes when creating anonymous function valuesJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-12ast: simplify declaration AST structureJo-Philipp Wich
Do not emit dummy T_ASSIGN nodes for plain variable declarations without initialization (`let foo` or `local foo`). This also allows simplifying `ut_check_for_in()` since we only need to deal with one common structure for both `for (... in ...)` and `for (local ... in ...)` cases. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-12syntax: implement key/value for-in loop iterationJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-10fs: do not close stdio streams when gc'ing scopeJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-10main: fix double free when using multiple -E optionsJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-10lexer: accept "let" as synonym for "local"Jo-Philipp Wich
This brings the utpl script syntax closer to ES5/ES6 and allows to use existing syntax highlightings in IDEs and editors. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-09syntax: properly handle list expressions in function callsJo-Philipp Wich
Ensure that a call like `fn((1, 2), 3)` invokes the function with arguments `2, 3` and not `1, 2, 3`. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-05eval: rework handling of list expressionsJo-Philipp Wich
Tune the grammar and rework the VM to properly yield the last result of list expressions in various contexts. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-05syntax: implement ES6-like arrow function syntaxJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-04tests: add illegal syntax tests for rest argumentsJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-04parser: zero-initialize expected token bitfieldJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-03syntax: implement ES6-like spread operatorJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-03syntax: implement ES6-like rest parameters for variadic functionsJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-02syntax: support `elif` clauses for alternative `if` syntaxJo-Philipp Wich
In the alternative `if` syntax mode, support a specific `elif` keyword instead of requiring an `else` branch followed by a disjunct `if` statement. The advantage is that templates do not require error-prone redundant `endif` keywords in else-if ladders. After this change, the following example: {% if (...): %} One condition {% else if (...): %} Another condition {% else if (...): %} A third condition {% else %} Final condition {% endif; endif; endif %} ... can be simplified into: {% if (...): %} One condition {% elif (...): %} Another condition {% elif (...): %} A third condition {% else %} Final condition {% endif %} Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-02ast: avoid null pointer deref in ut_new_exception()Jo-Philipp Wich
When reporting parse errors, we might not have a function context so avoid dereferencing it without checking. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-31main: allow prefixing -e and -E optionsJo-Philipp Wich
By specifying a name, followed by an equal sign before the actual option value, the corresponding JSON data is stored as global variable with the given name, instead of turning each object key into a variable itself. For example while `utpl -e '{ "foo": true, "bar": false }' ...` will set two variables `foo` and `bar`, the alternative syntax `utpl -e 'baz={ "foo": true, "bar": false }' ...` will declare a single variable `baz` holding the object `{ "foo": true, "bar": false }`. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-31lib: fix potential null pointer deref on not found cmdline moduleJo-Philipp Wich
When a module is requested via -m but not found on the system, we do not have a context opcode available when instantiating the exception, which leads to a segmentation faul when attempting to access the source text offset. Avoid the deref by checking the opcode pointer for non-null. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-31ast: fix potential null pointer deref in ut_free()Jo-Philipp Wich
Extend the existing `s != NULL` conditional to cover all state pointer accesses. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-31main: fix leading byte corruption when not starting with #!Jo-Philipp Wich
Reverse the order of the ungetc() calls to properly restore the first two probed bytes. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-19eval: fix memory leak in ut_execute_local()Jo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-19lib: fix memory leaks in printf() and sprintf()Jo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-19eval: fix leaking key value in object for-in loopsJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-19lib: let die() report the calling function, not itselfJo-Philipp Wich
2020-10-19eval: record correct source contexts in call stackJo-Philipp Wich
Also handle calls to C functions. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-19lib: forward exceptions in callback functionsJo-Philipp Wich
- Ensure that exceptions ocurring in sort(), filter(), replace() etc. callback functions are properly forwarded to the caller - Also fix invalid free() invocations in ut_replace() Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-19ast: fix scope double free in ut_free()Jo-Philipp Wich
Zero the scope object pointer in the scope structure before putting the JSON object in order to avoid a double-free by the scope's userdata destructor function. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-19eval: avoid ut_op deref after ut_execute_op() in ut_execute_local()Jo-Philipp Wich
Since we're invoking ut_execute_op() to obtain the assignment value, the operand pool might have been reallocated at a different memory address, invalidating the label opcode pointer. Obtain a reference to the underlying json label value and re-obtain the assignment opcode pointer with each iteration to avoid dereferencing stale pointers. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-18ast, eval: add recursion limitJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-18eval: fix segmentation faults with self-invoking functionsJo-Philipp Wich
Store the invocation scope and function context in the call stack frame and not in the function object to properly deal with recursive invocations. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-18lib: properly handle parse errors at EOFJo-Philipp Wich
At EOF, ut_parse_error() will receive 0 as token offset, which led to a null pointer dereference when creating the exception value. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-15eval: fix potential segfault in for() loopsJo-Philipp Wich
When a for() loop body, initializer, test or increment expression compiles further code, e.g. by invoking invoke() or require(), the opcode pool will be reallocated, potentially changing the addresses of all opcodes. This might lead to an invalid memory access when previously cached opcode pointers are accessed later on. Solve this issue by obtaining the relative offsets of the corresponding opcodes, avoiding the need for pointer dereferences. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-15syntax: allow consecutive case valuesJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-14eval: forward exceptions in `if` conditionsJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-14eval: expose complete exception object in catch {} blocksJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-14lib: selectively disable format string security checks for ut_printf_common()Jo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-14eval: get rid of alloca() allocationsJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-14treewide: unify error handlingJo-Philipp Wich
Get rid of the distinction between lexer/parser errors and runtime exceptions, use exceptions everywhere instead. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-14treewide: rework source file and callstack handlingJo-Philipp Wich
- Keep an open FILE* reference to processed source files in order to be able to rewind and extract error context later - Build a proper call stack when invoking utpl functions - Report call stack in exceptions Signed-off-by: Jo-Philipp Wich <jo@mein.io>