Age | Commit message (Collapse) | Author |
|
Add two new functions to deal with encoding and decoding of hexadecimal
digit strings:
- hexenc() - convert the given input value into a lower case hex digit
string, implicitely converting the input argument to a string value
if needed
- hexdec() - decode the given input hex digit string into a byte string,
skipping whitespace or optionally specified characters in the input
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Implement support for ECMAScript 6 template literals which allow simple
interpolation of variable values into strings without resorting to
`sprintf()` or manual string concatenation.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
When a managed function is indirectly invoked during bytecode execution,
e.g. when calling the tostring() method of an object prototype during
string concatenation, the invoked function must stop executing bytecode
upon return to hand control back to caller.
Extend `uc_vm_execute_chunk()` to track the amount of nested function
calls it performs and hand back control to the caller once the toplevel
callframe returns. Also bubble unhandled exceptions only as far as up
to the original caller.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
|
|
When invoking a native function as toplevel VM call which indirectly
triggers an unhandled exception in managed code, the callframes are
completely reset before the C function returns, leading to invalid
memory accesses when `uc_vm_call_native()` subsequently popped it's
own callframe again.
This issue did not surface by executing script code through the
interpreter since in this case the VM will always execute a managed
code as toplevel call, but it could be triggered by invoking a native
function triggering an exception through the C API using `uc_vm_call()`
on a fresh `uc_vm_t` context or by utilizing the CLI interpreters `-l`
flag to preload a native code library triggering an exception.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Do not continue loading other libraries or executing the main code if
loading one of the preload libraries fails.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Extend the `uc_json()` implementation to accept readable objects in
addition to plain input strings. This allows parsing JSON input directly
from open file handles, sockets or other kinds of producer objects without
the need to store the entire JSON source string intermediately in memory.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Make sure fs.dirname() doesn't truncate the last character of the
returned path. Previously ucv_string_new_length was called with a
length which no longer included the last character (which had just
been tested not to be a '/' or '.' and hence broke the loop at that
point).
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
[testcase added]
Signed-off-by: Paul Spooren <mail@aparcar.org>
[testcase folded into this commit and fixed]
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Treat the char value as unsigned when testing its value to yield consistent
results on both platforms with signed chars and those with unsigned chars
by default (e.g. ARM ones). This also avoids encoding byte values > 127 as
\uXXXX escape sequences, potentially breaking the strng contents.
Fixes: #62
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Add five new functions to deal with date calculation and timing:
- localtime(), gmtime() - return a broken down calendar date and time
specification from the given epoch (or now, if absent) in local and
UTC time respectively
- timelocal(), timegm() - the inverse operation for the former functions,
taking a date and time specification (interpreted as local or UTC time
respectively) and turning it into an epoch value
- clock() - return the second and nanosecond values of the system clock,
useful for time/performance measurements
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
lib: add argument position support (`%m$`) to `sprintf()` and `printf()`
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Different libc implementations produce different syntax error messages
on invalid regular expression patterns, so rework the test case to
produce stable output across all environments.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
A typo in the custom order function of the test case caused the test case
to yield differently sorted results on OS X, triggered by differences in
the libc's `qsort()` implementation.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Since OS X `getopt()` does not handle optional arguments, we need to
always pass a value to `-T`.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
This ensures that GNU readlink is preferred over OS X own readlink when
executing test cases. This is required due to lacking `-f` flag support
on OS X.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Let `require()` always evaluate the executed code in raw mode
- Let `render()` always evaluate the executed code in template mode
- Let `include()` inherit the raw mode semantics of the calling scope
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Change command line flags to be align better with those of other
interpreters and with the gcc compiler, e.g. `-D` and `-U` to
define and undefine globals, `-e` to execute script expression etc.
- Pass only excess CLI arguments as `ARGV` to scripts, e.g.
`ucode -e 'print("Hello world")' -- -x -y` would pass only
`[ "-x", "-y" ]` as ARGV contents
- Default to raw mode and introduce flag to enable template mode
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
When executing an object literal declaration using non-string computed
property name values, the VM crashed caused by an attempt to use a NULL
pointer (result of ucv_string_get() on a non-string value) as hash table
key.
Fix this issue by using the `ucv_key_set()` infrastructure which deals
with the implicit stringification of non-string key values.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Support ES2016 exponentiation (**) and exponentiation assignment (**=)
- Support ES2020 nullish coalescing (??) and logical nullish assignment (??=)
- Support ES2021 logical and assignment (&&=) and logical or assignment (||=)
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Fixes: 4ce69a8 ("fs: implement access(), mkstemp(), file.flush() and proc.flush()")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
When compiling a switch statement with duplicate `default` cases or a switch
statement with syntax errors before the body block, two error handling cases
were hit in the code that prematurely returned from the function without
resetting the compiler's patchlist pointer away from the on-stack patchlist
that had been set up for the switch statement.
Upon processing a subsequent break or continue control statement, a realloc
was performed on the then invalid patchlist contents, triggering a
segmentation fault or libc assert.
Solve this issue by not returning from the function but breaking the switch
body parsing loop.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
The most common usecase is extracting the value of a single byte at a
specific offset, e.g. to scan a string char-by-char to construct a hash.
Furthermore, constructing an array which contains the results of multiple
`ord()` invocations is trivial while efficiently extracting a single byte
value without the overhead of an intermediate array is not.
Due to that, change `ord()` to always return a single integer byte value
at the offset specified as second argument or at offset 0 in case no
argument was supplied.
That means that `ord("Abc", 0, 1, 2)` will now return `65` instead of the
former `[ 65, 98, 99 ]` result.
Code relying on the former behaviour should either perform multiple calls
to `ord()`, passing different offsets each time or switch to the `struct`
module which allows efficient unpacking of string data.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Due to using signed byte values when writing/reading short strings
to/from pointer addresses, 8 bit characters where incorrectly clamped
to `-1` (`255`).
Fix this issue by treating the input string as `uint8_t` array.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
When patching jump targets for break statments while compiling for-loop
statments, we need jump beyond the instructions popping intermediate loop
variables off the stack but before the pop instructions removing local
loop body variables to prevent a stack position mismatch between compiler
and vm.
Before that change, local loop body variables remained on the stack,
breaking the expected stack layout.
Fixes: b3d758b compiler: ("fix for/break miscompilation")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Ensure that that the testcase files are executed within the temporary
testcase work directory to simplify testing relative path resolution.
Also fixup the duplicate resource regression test breaking due to that.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
A performance shortcut in `ucv_is_equal()` incorrectly led to `NaN === NaN`
being true. Fix the issue by only comparing pointers when the involved
types are not doubles.
Due to fixing `NaN !== NaN`, the `uniq()` function now requires a special
case to treat multiple NaNs equal for the sake of generating an array of
unique values.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Fixes: b605dbf ("treewide: rework numeric value handling")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
The current implementation incorrectly yielded `true` for `0 == null` but
only `null` must be equal to `null`.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Rename 03_bugs to 04_bugs
- Rename 26_invalid_sparse_array_set to 27_invalid_sparse_array_set
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
The `touch` command result incorrectly shadowed the testcase exit code.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Introduce new command line flags `-o` and `-O` to write compiled program
code into the specified output file
- Add support for transparently executing precompiled files, the
lexical analyzing and com,pilation phase is skipped in this case
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Parse integer literals as unsigned numeric values in order to be able
to represent the entire unsigned 64bit value range
- Stop parsing minus-prefixed integer literals as negative numbers but
treat them as separate minus operator followed by a positive integer
instead
- Only store unsigned numeric constants in bytecode
- Rework numeric comparison logic to be able to handle full 64bit
unsigned integers
- If possible, yield unsigned 64 bit results for additions
- Simplify numeric value conversion API
- Compile code with -fwrapv for defined signed overflow semantics
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Introduce new operators `?.`, `?.[…]` and `?.(…)` to simplify looking up
deeply nested property chain in a secure manner.
The `?.` operator behaves like the `.` property access operator but yields
`null` if the left hand side is `null` or not an object.
Like `?.`, the `?.[…]` operator behaves like the `[…]` computed property
access but yields `null` if the left hand side is `null` or neither an
object or array.
Finally the `?.(…)` operator behaves like the function call operator `(…)`
but yields `null` if the left hand side is `null` or not a callable
function.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
When setting an array index which is beyond the end of the last currently
preallocated chunk and not evenly divisible by the chunk size, the array
entries list was not properly reallocated, resulting in invalid memory
writes.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
When compiling certain expressions as first statement of an ucode
program, e.g. a while loop in raw mode, a jump instruction to offset
zero is emitted which was incorrectly treated as placeholder by the
compiler.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
The Fuzz test implementation so far is just boilerplate and fails due to
imposed memory limits on the CI runner.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Set VM options and environment variables and load modules on the fly
while parsing the cli options instead of aggregating all the values in
memory first.
This vastly reduces the amount of arguments we need to pass to the
parse() function. Also rename parse() to compile() while we're at it.
Also slightly adjust the usage output.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Add a public getter and setter to read and set the VM trace level
respectively. Use the new API to control the trace mode with a newly
introduced `-t` command line switch.
Drop support for honouring the `TRACE` environment variable as
host programs embedding ucode might want to prevent that behaviour
or handle it differently.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Enabling raw code mode allows writing ucode scripts without any template
tag decorations (that is, without the need to provide an initial opening
'{%' tag).
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Skip interpreter lines in any source buffer and handle the skipping in the
lexer itself, to avoid reporting wrongly shifted token offsets to the
compiler, resulting in wrong error locations and source contexts.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|