summaryrefslogtreecommitdiffhomepage
path: root/tests
AgeCommit message (Collapse)Author
6 daystests: add crypto testsMikael Magnusson
Test RSA, ECDSA, and EdDSA signature verification, and key generation with message signing and verification. Signed-off-by: Mikael Magnusson <mikma@users.sourceforge.net>
2024-10-17Merge pull request #239 from jow-/safe-insert-during-obj-iterationJo-Philipp Wich
types: fix potential use after free on adding keys during iteration
2024-10-17types: fix potential use after free on adding keys during iterationJo-Philipp Wich
When keys are added to the object currently being iterated by a for loop, the insert operation might cause a hashtable resize with a subsequent memory reallocation and a different table base pointer, clobbering the entry pointers held by iterators pointing to the containing object of the resized table. In order to address this issue while keeping the iteration overhead low, extend the object key insert logic to check whether the insertion will trigger a reallocation and backup and restore the iterator pointers when needed. This slightly increases the size of the iterator states but the overhead for this should be neglectible as there'll only be a low amount of concurrently active iterations at any time. Fixes: #230 Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2024-10-16vallist: more thoroughly check for trailing garbage after numeric stringJo-Philipp Wich
When converting numeric strings into numbers, ensure that only optional trailing whitespace follows and no other characters. Fixes: #231 Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2024-09-23compiler: properly treat property names after spread expressionsJo-Philipp Wich
Ensure that unquoted property names following spread expressions in object declaration literals are not treated as keywords. Prior to this fix, an expression such as `{ ...someobj, default: 1 }` would result in a compile time syntax error. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2024-09-20Merge pull request #218 from jonasjelonek/add-ioctlJo-Philipp Wich
fs: add ioctl() file method
2024-09-20fs: add ioctl() file methodJonas Jelonek
implements ioctl() for a given file handle on Linux. Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2024-09-20lib: test if call to getenv() destroys environMikael Magnusson
Signed-off-by: Mikael Magnusson <mikma@users.sourceforge.net>
2024-07-29tests: replace test runner shell script with ucode implementationJo-Philipp Wich
The ucode interpreter and libraries are mature enough to execute their own testcases now, so replace the existing shell script with an equivalent ucode implementation. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2024-06-17fs: add lock() file methodFelix Fietkau
Implements file based locking on a given file handle. Signed-off-by: Felix Fietkau <nbd@nbd.name>
2024-06-17fs: add truncate() file methodFelix Fietkau
Trunates the file referenced by a file handle Signed-off-by: Felix Fietkau <nbd@nbd.name>
2024-03-13vm: rework `in` operator semanticsJo-Philipp Wich
- Ensure that testing for array membership does strict equality tests - Ensure that `(NaN in [ NaN ]) == true` - Do not perform implicit value conversion when testing for object keys, to avoid nonsensical results such as `([] in { "[ ]": true }) == true` - Add test cases for the `in` operator Fixes: #193 Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2024-02-21vm: rework object iterationJo-Philipp Wich
Ensure that deleting object keys during iteration is safe by keeping a global chain of per-object iterators which are advanced to the next key when the entry that is about to be iterated is deleted. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2024-02-13compiler: close upvalues on loop control statementsFelix Fietkau
When removing locals from all scopes, upvalues need to be considered like in uc_compiler_leave_scope(). Closing them is required to avoid leaving lingering references to stack values that went out of scope, which would lead to invalid memory accesses in subsequent code when such upvalues are used by closures. Fixes: #187 Signed-off-by: Felix Fietkau <nbd@nbd.name> [add testcase, reword commit message] Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2023-11-06syntax: don't treat `as` and `from` as reserved keywordsJo-Philipp Wich
ECMAScript allows using `as` and `from` as identifiers so follow suit and don't treat them specially while parsing. Extend the compiler logic instead to check for TK_LABEL tokens with the expected value to properly parse import and export statements. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2023-10-09types: ensure double serializatiion with decimal placesJo-Philipp Wich
The `%g` printf format used for serializing double values into strings will not include any decimal place if the value happens to be integral, leading to an unwanted double to integer conversion when serializing and subsequently deserializing an integral double value as JSON. Solve this issue by checking the serialized string result for a decimal point or exponential notation and appending `.0` if neither is found. Ref: #173 Suggested-by: Felix Fietkau <nbd@nbd.name> Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2023-08-22types: improve comparison reliability of binary stringsJo-Philipp Wich
The existing `ucv_compare()` implementation utilized `strcmp()` to compare two ucode string values, which may lead to incorrect results for strings containing null bytes as the comparison prematurely aborts when encountering the first null. Rework the string comparison logic to use `memcmp()` for comparing both ucv strings with each other in order to ensure that expressions such as `"" == "\u0000"` lead to the expected `false` result. Ref: https://github.com/openwrt/luci/issues/6530 Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2023-07-27main: enable signal dispatching in the standalone cli interpreterJo-Philipp Wich
Enable signal dispatching by default for standalone ucode programs. Also adjust the `gc()` testcase output as the default number of allocations with enabled signal dispatching changes slightly. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2023-07-12source: fix source offset accountingJo-Philipp Wich
- When skipping the interpreter line, don't count it's newline twice - Fix reporting byte offsets beyond the end of line Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2023-05-30lib: support object ordering in `uc_sort()`Jo-Philipp Wich
Extend `uc_sort()` to utilize `ucv_object_sort()` in order to support reordering object keys. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2023-05-27main: add user specified library search paths before default pathFelix Fietkau
Allow -L to add library paths that take precedence over the built-in ones. Signed-off-by: Felix Fietkau <nbd@nbd.name>
2023-01-23types: fix array unshift operations and add test coverageJo-Philipp Wich
- Fix `ucv_array_unshift()` improperly rejecting operation on empty arrays - Fix `uc_unshift()` improperly reversing maintaining argument order - Add missing test coverage for `push()`, `pop()`, `unshift()` and `shift()` array operations. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2023-01-09fs: add `isatty()` functionPetr Štetiar
Expose the `isatty(3)` libc function in the fs module to allow checking whether a file descriptor refers to a terminal. Signed-off-by: Petr Štetiar <ynezz@true.cz>
2022-12-02tests: fixup testcasesJo-Philipp Wich
Adjust expected testcase outputs after double format change in the previous commit. Fixes: 4c654df ("types: adjust double printing format") Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-11-29compiler: fix bytecode for logical assignments of propertiesJo-Philipp Wich
The compiler emitted incorrect bytecode for logical assignment operations on property expressions. The generated instructions left the stack in an unclean state when the assignment condition was not fulfilled, causing a stack layout mismatch between compiler and vm, leading to undefined variable accesses and other non-deterministic behavior. Solve this issue by rewriting the bytecode generation to yield an instruction sequence that does not leave garbage on the stack. The implementation is not optimal yet, as an expression in the form `obj.prop ||= val` will load `obj.prop` twice. This is acceptable for now as the load operation has no side effect, but should be solved in a better way by introducing new instructions that allow for swapping stack slots, allowing the vm to operate on a copy of the loaded value. Also rewrite the corresponding test case to trigger a runtime error on code versions before this fix. Fixes: fdc9b6a ("compiler: fix `??=`, `||=` and `&&=` logical assignment semantics") Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-11-29tests: relax sleep() testJo-Philipp Wich
Invoking `sleep(1000)` in the CI container often sleeps slightly longer than exactly 1000ms, causing the test output to mismatch. Relax the test requirement to simply ensure that t2 > t1. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-11-22compiler: ensure that arrow functions with block bodies return no valueJo-Philipp Wich
Follow ES6 semantics and ensure that arrow functions with a block body don't implicitly return the value of the last executed statement. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-11-15compiler: fix `??=`, `||=` and `&&=` logical assignment semanticsJo-Philipp Wich
When compiling logical assignment expressions, ensure that the right hand side of the assignment is not evaluated when the assignment condition is unfulfilled. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-10-05lexer: fixes for regex literal parsingJo-Philipp Wich
- Ensure that regexp extension escapes are consistently handled; substitute `\d`, `\D`, `\s`, `\S`, `\w` and `\W` with `[[:digit:]]`, `[^[:digit:]]`, `[[:space:]]`, `[^[:space:]]`, `[[:alnum:]_]` and `[^[:alnum:]_]` character classes respectively since not all POSIX regexp implementations implement all of those extensions - Preserve `\b`, `\B`, `\<` and `\>` boundary matches Fixes: a45f2a3 ("lexer: improve regex literal handling") Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-10-04lib: implement slice() functionJo-Philipp Wich
Implement a new function `slice()` to complement the existing `splice()` function and model it's semantics after the ES6 `Array.slice()` version. Fixes: #106 Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-10-04main: implement print modeJo-Philipp Wich
Introduce a new `-p` flag which works like `-e` but prints the final expression result. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-10-04compiler: optimize function return opcode generationJo-Philipp Wich
Track last emitted statement type in compiled code and only generate final `return null` opcodes if there is no preceeding `return` statement. Also use this statement tracking to avoid emitting invalid return opcodes for arrow function bodies with trailing empty statements. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-10-04lexer: improve regex literal handlingJo-Philipp Wich
- Do not treat slashes within bracket expressions as delimitters - Do not escape slashes when stringifying regex sources - Allow all escape sequence types in regex literals Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-09-30vm: maintain export symbol tables per programJo-Philipp Wich
Instead of having one global export table per VM instance maintain one table per program instance. This is required to avoid clobbering the export list in case `import` using code is loaded at runtime through `require()`, `loadfile()` etc. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-09-05lib: add limit support to split() and replace()Jo-Philipp Wich
Extend the split() and replace() functions to accept an additional optional `limit` argument which limits the amount of split operations / substitutions performed by these functions. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-29lib: extend render() to support function valuesJo-Philipp Wich
Extend the `render()` function to accept a function value as first argument, which allows running arbitrary ucode functions and capturing their output. This is especially useful in conjunction with `loadfile()` or `loadstring()` to dynamically compile templates and rendering their output into a string. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-29lib: improve getenv() and split() implementationsJo-Philipp Wich
- getenv(): Allow querying the entire environment by omiting variable name - split(): Properly handle null bytes in subject and separator strings Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-24lib: introduce three new functions call(), loadstring() and loadfile()Jo-Philipp Wich
Introduce new functions dealing with on-the-fly compilation of code and execution of functions with different global scope. The `loadstring()` and `loadfile()` functions will compile the given ucode source string or ucode file path respectively and return the entry function of the resulting program. An optional dictionary specifying parse options may be given as second argument. Both functions return `null` on invalid arguments and throw an exception in case of compilation errors. The `call()` function allows invoking a given function value with a different `this` context and/or a different global environment. Finally refactor the existing `uc_require_ucode()` implementation to reuse the new `uc_loadfile()` and `uc_call()` implementations and adjust as well as simplify affected testcases. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-12main: introduce -g flag to allow enabling periodic gc from cliJo-Philipp Wich
Implement a new flag `-g` which takes an interval value and enables the periodic GC with the given interval for cyclic object structures in the VM if specified. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-12lib: implement gc()Jo-Philipp Wich
Introduce a new stdlib function `gc()` which allows controlling the periodic garbage collector from ucode. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-06compiler: add import statement support for dynamic extensionsJo-Philipp Wich
Utilize the new I_DYNLINK vm opcode to support import statements referring to dynamic extension modules. During compilation, the compiler will try to infer the type of the imported module from the resolved file path; if it ends with `.so`, the module is assumed to by a dynamic extension and loading/binding of the module is deferred to runtime using I_DYNLINK opcodes. Additionally, the `-c` cli option gained support for a new compiler flag `dynlink=...` which allows forcing a particular module name expression to be treated as dynamic extension. This is useful to e.g. force resolving `import { x } from "foo"` to a dynamic extension `foo.so` loaded at runtime even if a plain `foo.uc` exists in the search path during compilation or if no such module is available at build time. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-06compiler: don't treat offset 0 special at syntax errorsJo-Philipp Wich
If a compile error is raised at offset 0, try to resolve line and character position anyway. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-05compiler: improve formatting of nested syntax error messagesJo-Philipp Wich
Indent inner messages and prepend them with a vertical bar to increase visual separation of messages. Also include file name in source context output when the compiled program contains more than one source file. Adjust affected testcase outputs accordingly. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-05compiler: rework export index allocationJo-Philipp Wich
The current implementation of the module export offset tracking was inadequate and failed to properly handle larger module dependency graphs. In order to properly support nested module imports/exports, the following changes have been introduced: - Gather export slots during module compilation and emit corresponding export opcodes as one contiguous block at the end of the module function body, right before the final return. This ensures that interleaved imports of other modules do not place foreign exports between our module exports. - Track the number of program wide allocated export slots in order to derive per-module-source offsets for the global VM export list. - Derive import opcode source index from the module source export offset and the index of the requested name within the module source export name list. - Improve error reporting for circular module imports. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-30compiler: add support for import/export statementsJo-Philipp Wich
This commit introduces syntax level support for ES6 style module import and export statements. Imports are resolved at compile time and the corresponding module code is compiled into the main program. Also add testcases to cover import and export statement semantics. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-30tests: run_tests.sh: substitute dynamic test directory path in outputJo-Philipp Wich
Replace all occurrences for the test file directory path with "." in stderr and stdout results to ensure stable test outputs. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-28lexer: rewrite token scannerJo-Philipp Wich
- Use nested switches instead of lookup tables to detect tokens - Simplify input buffer logic - Reduce amount of intermediate states Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-12lexer: fix parsing with disabled block left strippingJo-Philipp Wich
When a template was parsed with global block left stripping disabled, then any text preceding an expression or statement block start tag was incorrectly prepended to the first token value of the block, leading to syntax errors in the compiler. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-06-30compiler: fix stack mismatch on continue statements nested in switchesJo-Philipp Wich
When compiling continue statements nested in switches, the compiler only emitted pop statements for the local variables in the switch body scope, but not for the locals in the scope(s) leading up to the containing loop body. Extend the compilers internal patchlist structure to keep track of the type of scope tied to the patchlist and extend `continue` statement compilation logic to select the appropriate parent patch list in order to determine the amount of locals (stack slots) to clear before the emitted jump instruction. As a result, the `uc_compiler_backpatch()` implementation can be simplified somewhat since we do not need to propagate entries to parent lists anymore. Also add a further regression test case to cover this issue. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-06-27compiler: fix stack mismatch on nonmatching switch statements with localsJo-Philipp Wich
When a switch statement containing cases with local variable declarations and no default case is evalulated and none of the the cases matched, the local variable slots were never initialized but got popped off the stack when execution resumed after the switch scope, leading to a mismatch in stack layout between compiler and runtime, causing local variables to yield wrong values or a stack underflow triggering a segmentation fault. Solve this issue by patching the last conditional case match jump to hop beyond the local variable pop instructions when no default case is defined. Also extend the regression test case dealing with other switch related stack mismatch issues to cover this particular problem as well. Signed-off-by: Jo-Philipp Wich <jo@mein.io>