diff options
author | Jo-Philipp Wich <jo@mein.io> | 2022-01-23 22:21:24 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2022-01-26 10:47:56 +0100 |
commit | 04fa2baba6d615c49cf3f77986595da2a7783899 (patch) | |
tree | a346cc4d4fd630797dcc91aeb35f2d7bdf44233b /tests/custom/04_bugs | |
parent | abe38e7e390cc17e6eae0ebe94d2006c548e095c (diff) |
tests: reorganize testcase files
- 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>
Diffstat (limited to 'tests/custom/04_bugs')
27 files changed, 746 insertions, 0 deletions
diff --git a/tests/custom/04_bugs/01_try_catch_stack_mismatch b/tests/custom/04_bugs/01_try_catch_stack_mismatch new file mode 100644 index 0000000..f6e5a0a --- /dev/null +++ b/tests/custom/04_bugs/01_try_catch_stack_mismatch @@ -0,0 +1,52 @@ +When compiling a try/catch statement with an exception variable, the catch +skip jump incorrectly pointed to the POP instruction popping the exception +variable off the stack, leading to a stack position mismatch between +compiler and vm, causing local variables to yield wrong values at runtime. + +-- Expect stdout -- +1 +-- End -- + +-- Testcase -- +{% + function f() { + let x; + + try { + x = 1; + } + catch(e) { + + } + + // Before the fix, `x` incorrectly yielded the print function value + print(x, "\n"); + } + + f() +%} +-- End -- + + +When compiling a try/catch statement with local variable declearations +within the try block, the catch skip jump incorrectly happened before the +local try block variables were popped off the stack, leading to a stack +position mismatch between compiler and vm, causing local variables to +yield wrong values at runtime. + +-- Expect stdout -- +1 +-- End -- + +-- Testcase -- +{% + try { + let a; + } + catch {} + + let b = 1; + + print(b, "\n"); +%} +-- End -- diff --git a/tests/custom/04_bugs/02_array_pop_use_after_free b/tests/custom/04_bugs/02_array_pop_use_after_free new file mode 100644 index 0000000..22f63ff --- /dev/null +++ b/tests/custom/04_bugs/02_array_pop_use_after_free @@ -0,0 +1,14 @@ +When popping an element off an array, especially the last one, the popped +value might have been freed before the refcount was increased later on +function return. + +-- Expect stdout -- +1 +-- End -- + +-- Testcase -- +{% + x = [1]; + print(pop(x), "\n"); // This caused a SIGABRT before the bugfix +%} +-- End -- diff --git a/tests/custom/04_bugs/03_switch_fallthrough_miscompilation b/tests/custom/04_bugs/03_switch_fallthrough_miscompilation new file mode 100644 index 0000000..3e6410e --- /dev/null +++ b/tests/custom/04_bugs/03_switch_fallthrough_miscompilation @@ -0,0 +1,16 @@ +When falling through from a matched switch case into the default case, +the compiler incorrectly emitted bytecode that led to an endless loop. + +-- Expect stdout -- +1 +-- End -- + +-- Testcase -- +{% + switch (1) { + case 1: + default: + print("1\n"); + } +%} +-- End -- diff --git a/tests/custom/04_bugs/04_property_set_abort b/tests/custom/04_bugs/04_property_set_abort new file mode 100644 index 0000000..8af477f --- /dev/null +++ b/tests/custom/04_bugs/04_property_set_abort @@ -0,0 +1,76 @@ +When attempting to set a property on a non-array, non-object value the +VM aborted due to an assert triggered by libjson-c. + +-- Testcase -- +{% (null).x = 1 %} +-- End -- + +-- Expect stderr -- +Type error: attempt to set property on null value +In line 1, byte 15: + + `{% (null).x = 1 %}` + Near here ----^ + + +-- End -- + + +-- Testcase -- +{% (1).x = 1 %} +-- End -- + +-- Expect stderr -- +Type error: attempt to set property on integer value +In line 1, byte 12: + + `{% (1).x = 1 %}` + Near here -^ + + +-- End -- + + +-- Testcase -- +{% (1.2).x = 1 %} +-- End -- + +-- Expect stderr -- +Type error: attempt to set property on double value +In line 1, byte 14: + + `{% (1.2).x = 1 %}` + Near here ---^ + + +-- End -- + + +-- Testcase -- +{% (true).x = 1 %} +-- End -- + +-- Expect stderr -- +Type error: attempt to set property on boolean value +In line 1, byte 15: + + `{% (true).x = 1 %}` + Near here ----^ + + +-- End -- + + +-- Testcase -- +{% ("test").x = 1 %} +-- End -- + +-- Expect stderr -- +Type error: attempt to set property on string value +In line 1, byte 17: + + `{% ("test").x = 1 %}` + Near here ------^ + + +-- End -- diff --git a/tests/custom/04_bugs/05_duplicate_ressource_type b/tests/custom/04_bugs/05_duplicate_ressource_type new file mode 100644 index 0000000..21166b2 --- /dev/null +++ b/tests/custom/04_bugs/05_duplicate_ressource_type @@ -0,0 +1,31 @@ +When requiring a C module that registers custom ressource types multiple +times, ressource values instantiated after subsequent requires of the +same extensions didn't properly function since the internal type prototype +was resolved to the initial copy and subsequently discarded due to an index +mismatch. + +-- Testcase -- +{% + fs = require("fs"); + fd = fs.open("README.md"); + + printf("fd.read() #1: %s\n", + fd.read("line") ? "working" : "not working (" + fd.error() + ")"); + + fd.close(); + + + fs = require("fs"); + fd = fs.open("README.md"); + + printf("fd.read() #2: %s\n", + fd.read("line") ? "working" : "not working (" + fd.error() + ")"); + + fd.close(); +%} +-- End -- + +-- Expect stdout -- +fd.read() #1: working +fd.read() #2: working +-- End -- diff --git a/tests/custom/04_bugs/06_lexer_escape_at_boundary b/tests/custom/04_bugs/06_lexer_escape_at_boundary new file mode 100644 index 0000000..e80b0a1 --- /dev/null +++ b/tests/custom/04_bugs/06_lexer_escape_at_boundary @@ -0,0 +1,12 @@ +When the lexer processed a backslash introducing a string escape directly +at the buffer boundary, the backslash was incorrectly retained. + +-- Testcase -- +{% + print("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl\n"); +%} +-- End -- + +-- Expect stdout -- +abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl +-- End -- diff --git a/tests/custom/04_bugs/07_lexer_overlong_lines b/tests/custom/04_bugs/07_lexer_overlong_lines new file mode 100644 index 0000000..d2dd3be --- /dev/null +++ b/tests/custom/04_bugs/07_lexer_overlong_lines @@ -0,0 +1,13 @@ +A logic flaw in the lineinfo encoding function led to an endless tight +loop when a buffer chunk with 128 byte got consumed, which may happen +when parsing very long literals. + +-- Testcase -- +{% + print("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg\n"); +%} +-- End -- + +-- Expect stdout -- +abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg +-- End -- diff --git a/tests/custom/04_bugs/08_compiler_arrow_fn_expressions b/tests/custom/04_bugs/08_compiler_arrow_fn_expressions new file mode 100644 index 0000000..5cd8960 --- /dev/null +++ b/tests/custom/04_bugs/08_compiler_arrow_fn_expressions @@ -0,0 +1,15 @@ +Arrow functions with single expression bodies were parsed with a wrong +precedence level, causing comma expressions to be greedily consumed. + +-- Testcase -- +{% + print({ + a: () => 1, + b: () => 2 + }, "\n"); +%} +-- End -- + +-- Expect stdout -- +{ "a": "() => { ... }", "b": "() => { ... }" } +-- End -- diff --git a/tests/custom/04_bugs/09_reject_invalid_array_indexes b/tests/custom/04_bugs/09_reject_invalid_array_indexes new file mode 100644 index 0000000..a7e5272 --- /dev/null +++ b/tests/custom/04_bugs/09_reject_invalid_array_indexes @@ -0,0 +1,25 @@ +Since libjson-c's json_object_get_int64() returns 0 for any input value +that has no integer representation, any kind of invalid array index +incorrectly yielded the first array element. + +-- Testcase -- +{% + x = [1, 2, 3]; + + print([ + x[1], + x["1"], + x[1.0], + x[1.1], + x.foo, + x["foo"], + x["0abc"], + x[x], + x[{ foo: true }] + ], "\n"); +%} +-- End -- + +-- Expect stdout -- +[ 2, 2, 2, null, null, null, null, null, null ] +-- End -- diff --git a/tests/custom/04_bugs/10_break_stack_mismatch b/tests/custom/04_bugs/10_break_stack_mismatch new file mode 100644 index 0000000..ae16dac --- /dev/null +++ b/tests/custom/04_bugs/10_break_stack_mismatch @@ -0,0 +1,38 @@ +When emitting jump instructions for breaking out of for-loops, the compiler +incorrectly set the jump target before the pop instruction clearing the +intermediate loop variables. Since the break instruction itself already +compiles to a series of pop instructions reverting the stack to it's the +pre-loop state, intermediate values got popped twice, leading to a stack +layout mismatch between compiler and VM, resulting in wrong local variable +values or segmentation faults at runtime. + +-- Testcase -- +{% + let x = 1; + + for (let y in [2]) + break; + + print(x, "\n"); +%} +-- End -- + +-- Expect stdout -- +1 +-- End -- + + +-- Testcase -- +{% + let x = 1; + + for (let y = 0; y < 1; y++) + break; + + print(x, "\n"); +%} +-- End -- + +-- Expect stdout -- +1 +-- End -- diff --git a/tests/custom/04_bugs/11_switch_stack_mismatch b/tests/custom/04_bugs/11_switch_stack_mismatch new file mode 100644 index 0000000..cc3b41a --- /dev/null +++ b/tests/custom/04_bugs/11_switch_stack_mismatch @@ -0,0 +1,39 @@ +When jumping into a case following prior cases declaring local variables, +the preceding local variable declarations were skipped, leading to an +unexpected stack layout which caused local variables to carry wrong +values at run time and eventual segmentation faults when attempting to +unwind the stack on leaving the lexical switch scope. + +-- Expect stdout -- +Matching 1: + - 1: [ null, null, 3, 4 ] + - 2: [ null, null, 3, 4, 5, 6 ] +Matching 2: + - 2: [ null, null, null, null, 5, 6 ] +Matching 3: + - default: [ 1, 2 ] + - 1: [ 1, 2, 3, 4 ] + - 2: [ 1, 2, 3, 4, 5, 6 ] +-- End -- + +-- Testcase -- +{% + for (let n in [1, 2, 3]) { + printf("Matching %d:\n", n); + + switch (n) { + default: + let x = 1, y = 2; + print(" - default: ", [x, y], "\n"); + + case 1: + let a = 3, b = 4; + print(" - 1: ", [x, y, a, b], "\n"); + + case 2: + let c = 5, d = 6; + print(" - 2: ", [x, y, a, b, c, d], "\n"); + } + } +%} +-- End -- diff --git a/tests/custom/04_bugs/12_altblock_stack_mismatch b/tests/custom/04_bugs/12_altblock_stack_mismatch new file mode 100644 index 0000000..e350660 --- /dev/null +++ b/tests/custom/04_bugs/12_altblock_stack_mismatch @@ -0,0 +1,83 @@ +When compiling alternative syntax blocks, such as `for ...: endfor`, +`if ...: endif` etc., the compiler didn't assign the contained statements +to a dedicated lexical scope, which caused a stack mismatch between +compiler and vm when such blocks declaring local variables weren't +actually executed. + +-- Expect stdout -- +2 +-- End -- + +-- Testcase -- +{% + if (false): + let a = 1; + endif; + + /* Due to lack of own lexical scope above, the compiler assumed + * that `a` is still on stack but the code to initialize it was + * never executed, so stack offsets were shifted by one from here + * on throughout the rest of the program. */ + + let b = 2; + + print(b, "\n"); +%} +-- End -- + + +Test a variation of the bug using `for in..endfor` loop syntax. + +-- Expect stdout -- +2 +-- End -- + +-- Testcase -- +{% + for (let x in []): + let a = 1; + endfor; + + let b = 2; + + print(b, "\n"); +%} +-- End -- + + +Test a variation of the bug using `for..endfor` count loop syntax. + +-- Expect stdout -- +2 +-- End -- + +-- Testcase -- +{% + for (let i = 0; i < 0; i++): + let a = 1; + endfor; + + let b = 2; + + print(b, "\n"); +%} +-- End -- + + +Test a variation of the bug using `while..endwhile` loop syntax. + +-- Expect stdout -- +2 +-- End -- + +-- Testcase -- +{% + while (false): + let a = 1; + endwhile; + + let b = 2; + + print(b, "\n"); +%} +-- End -- diff --git a/tests/custom/04_bugs/13_split_by_string_leading_trailing b/tests/custom/04_bugs/13_split_by_string_leading_trailing new file mode 100644 index 0000000..10a6062 --- /dev/null +++ b/tests/custom/04_bugs/13_split_by_string_leading_trailing @@ -0,0 +1,11 @@ +When splitting a string, the existing uc_split() implementation failed +to produce an empty leading and trailing result array element when the +subject string started or ended with a delimitter. + +-- Expect stdout -- +[ "", "foo", "" ] +-- End -- + +-- Testcase -- +{{ split("/foo/", "/") }} +-- End -- diff --git a/tests/custom/04_bugs/14_incomplete_expression_at_eof b/tests/custom/04_bugs/14_incomplete_expression_at_eof new file mode 100644 index 0000000..474e87c --- /dev/null +++ b/tests/custom/04_bugs/14_incomplete_expression_at_eof @@ -0,0 +1,16 @@ +When an incomplete expression was parsed at the very end of the input +buffer, the source code context line was not properly printed. + +-- Expect stderr -- +Syntax error: Expecting expression +In line 1, byte 7: + + `{% 1+` + ^-- Near here + + +-- End -- + +-- Testcase -- +{% 1+ +-- End -- diff --git a/tests/custom/04_bugs/15_segfault_on_prefix_increment b/tests/custom/04_bugs/15_segfault_on_prefix_increment new file mode 100644 index 0000000..280b680 --- /dev/null +++ b/tests/custom/04_bugs/15_segfault_on_prefix_increment @@ -0,0 +1,18 @@ +When parsing an invalid pre- or post-decrement expression as first +statement of a source buffer, the compiler crashed while attempting +to look up the type of the previous instruction within a not-yet +allocated chunk buffer. + +-- Expect stderr -- +Syntax error: Unterminated string +In line 1, byte 6: + + `{% ++"` + ^-- Near here + + +-- End -- + +-- Testcase -- +{% ++" +-- End -- diff --git a/tests/custom/04_bugs/16_hang_on_regexp_at_eof b/tests/custom/04_bugs/16_hang_on_regexp_at_eof new file mode 100644 index 0000000..d8702ca --- /dev/null +++ b/tests/custom/04_bugs/16_hang_on_regexp_at_eof @@ -0,0 +1,9 @@ +When parsing a regexp literal at the end of the source buffer, the lexer +ended up in an infinite loop watining for a non-flag character. + +-- Expect stdout -- +-- End -- + +-- Testcase -- +{% /a/ +-- End (no-eol) -- diff --git a/tests/custom/04_bugs/17_hang_on_unclosed_expression_block b/tests/custom/04_bugs/17_hang_on_unclosed_expression_block new file mode 100644 index 0000000..25128bb --- /dev/null +++ b/tests/custom/04_bugs/17_hang_on_unclosed_expression_block @@ -0,0 +1,16 @@ +When parsing an unclosed expression block, the lexer did end up in an +infinite loop. + +-- Expect stderr -- +Syntax error: Unterminated template block +In line 1, byte 6: + + `{{ 1` + ^-- Near here + + +-- End -- + +-- Testcase -- +{{ 1 +-- End -- diff --git a/tests/custom/04_bugs/18_hang_on_line_comments_at_eof b/tests/custom/04_bugs/18_hang_on_line_comments_at_eof new file mode 100644 index 0000000..957ed47 --- /dev/null +++ b/tests/custom/04_bugs/18_hang_on_line_comments_at_eof @@ -0,0 +1,31 @@ +When parsing a comment near EOF, or a comment escaping the end +of an expression block, the lexer did end up in an infinite loop. + +-- Expect stderr -- +Syntax error: Expecting expression +In line 1, byte 9: + + `{{ // }}` + ^-- Near here + + +-- End -- + +-- Testcase -- +{{ // }} +-- End -- + + +-- Expect stderr -- +Syntax error: Unterminated comment +In line 1, byte 4: + + `{{ /* }}` + ^-- Near here + + +-- End -- + +-- Testcase -- +{{ /* }} +-- End -- diff --git a/tests/custom/04_bugs/19_truncated_format_string b/tests/custom/04_bugs/19_truncated_format_string new file mode 100644 index 0000000..8ddd0a3 --- /dev/null +++ b/tests/custom/04_bugs/19_truncated_format_string @@ -0,0 +1,14 @@ +When processing a truncated format string, uc_printf_common() - which is +used by `sprintf()` and `printf()` in ucode - appended trailing garbage +to the resulting string. + +-- Expect stdout -- +[ 37, null ] +-- End -- + +-- Testcase -- +{% + let s = sprintf("%"); + print(ord(s, 0, 1), "\n"); +%} +-- End -- diff --git a/tests/custom/04_bugs/20_use_strict_stack_mismatch b/tests/custom/04_bugs/20_use_strict_stack_mismatch new file mode 100644 index 0000000..7294d23 --- /dev/null +++ b/tests/custom/04_bugs/20_use_strict_stack_mismatch @@ -0,0 +1,17 @@ +When compiling the `use strict` statement, the compiler omitted the +corresponding load instruction, leading to a mismatch of the expected +stack layout between compiler and VM. + +-- Expect stdout -- +1 +-- End -- + +-- Testcase -- +{% + "use strict"; + + let x = 1; + + print(x, "\n"); +%} +-- End -- diff --git a/tests/custom/04_bugs/21_compiler_parenthesized_prop_keyword b/tests/custom/04_bugs/21_compiler_parenthesized_prop_keyword new file mode 100644 index 0000000..472b2af --- /dev/null +++ b/tests/custom/04_bugs/21_compiler_parenthesized_prop_keyword @@ -0,0 +1,17 @@ +When compiling a parenthesized property access expression, the compiler +didn't instruct the lexer to treat a potential subsequent keyword as label, +leading to an incorrect syntax error exception. + +-- Expect stdout -- +true +true +-- End -- + +-- Testcase -- +{% + let x = { default: true }; + + print(x.default, "\n"); // this was okay + print((x.default), "\n"); // this failed +%} +-- End -- diff --git a/tests/custom/04_bugs/22_compiler_break_continue_scoping b/tests/custom/04_bugs/22_compiler_break_continue_scoping new file mode 100644 index 0000000..461b144 --- /dev/null +++ b/tests/custom/04_bugs/22_compiler_break_continue_scoping @@ -0,0 +1,59 @@ +When compiling a break or continue statement, the compiler emitted pop +instructions for local variables within the scope the break or continue +keyword appeared in, but it must also pop local variables in enclosing +scopes up until the scope of the containing loop or switch body. + +-- Expect stdout -- +1 +2 +3 +-- End -- + +-- Testcase -- +{% + for (let i = 1; i <= 3; i++) { + while (true) { + let n = i; + + print(n, "\n"); + + { + // The `let n` stack slot is not popped since it is + // outside of break's scope... + break; + } + } + } +%} +-- End -- + +-- Expect stdout -- +1 +2 +3 +2 +4 +6 +3 +6 +9 +-- End -- + +-- Testcase -- +{% + for (let i = 1; i <= 3; i++) { + for (let j = 1; j <= 3; j++) { + let n = i * j; + + print(n, "\n"); + + if (j == 1) + { + // The `let n` stack slot is not popped since it is + // outside of continue's scope... + continue; + } + } + } +%} +-- End -- diff --git a/tests/custom/04_bugs/23_compiler_parenthesized_division b/tests/custom/04_bugs/23_compiler_parenthesized_division new file mode 100644 index 0000000..a70703f --- /dev/null +++ b/tests/custom/04_bugs/23_compiler_parenthesized_division @@ -0,0 +1,19 @@ +When compiling a parenthesized division or division-assignment expression, +the compiler didn't instruct the lexer to treat a potential subsequent +slash as operand, leading to an incorrect syntax error exception. + +-- Expect stdout -- +0 +0 +0 +0 +-- End -- + +-- Testcase -- +{% + print(a / 1, "\n"); // this was okay + print(a /= 1, "\n"); // okay too + print((a / 1), "\n"); // this failed + print((a /= 1), "\n"); // failed as well +%} +-- End -- diff --git a/tests/custom/04_bugs/24_compiler_local_for_loop_declaration b/tests/custom/04_bugs/24_compiler_local_for_loop_declaration new file mode 100644 index 0000000..aafde55 --- /dev/null +++ b/tests/custom/04_bugs/24_compiler_local_for_loop_declaration @@ -0,0 +1,18 @@ +When compiling a for-loop local variable initializer expression, the compiler +incorrectly treated subsequent declarations as global variable assignments, +triggering reference error exceptions in strict mode. + +-- Expect stdout -- +1 +-- End -- + +-- Testcase -- +{% + "use strict"; + + // The initializer expression below was incorrectly interpreted as + // `let x = 0; y = 1` instead of the correct `let ..., y = 1`. + for (let x = 0, y = 1; x < 1; x++) + print(y, "\n"); +%} +-- End -- diff --git a/tests/custom/04_bugs/25_lexer_shifted_offsets b/tests/custom/04_bugs/25_lexer_shifted_offsets new file mode 100644 index 0000000..db10121 --- /dev/null +++ b/tests/custom/04_bugs/25_lexer_shifted_offsets @@ -0,0 +1,21 @@ +When lexing a source buffer with a non-zero offset, e.g. due to a +skipped interpreter line, lexical tokens reported a wrong offset +to the compiler, causing error locations and source context lines +to be incorrectly shifted. + +-- Testcase -- +#!/usr/bin/env ucode +{% + die("Error"); +%} +-- End -- + +-- Expect stderr -- +Error +In line 3, byte 12: + + ` die("Error");` + Near here -----^ + + +-- End -- diff --git a/tests/custom/04_bugs/26_compiler_jmp_to_zero b/tests/custom/04_bugs/26_compiler_jmp_to_zero new file mode 100644 index 0000000..e7e0127 --- /dev/null +++ b/tests/custom/04_bugs/26_compiler_jmp_to_zero @@ -0,0 +1,17 @@ +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. + +-- Testcase -- +while (i++ < 1) + print("Test\n"); +-- End -- + +-- Args -- +-R +-- End -- + +-- Expect stdout -- +Test +-- End -- diff --git a/tests/custom/04_bugs/27_invalid_sparse_array_set b/tests/custom/04_bugs/27_invalid_sparse_array_set new file mode 100644 index 0000000..4c47039 --- /dev/null +++ b/tests/custom/04_bugs/27_invalid_sparse_array_set @@ -0,0 +1,49 @@ +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. + +-- Testcase -- +{% + for (i = 0; i < 32; i++) { + a = []; + a[i] = true; + print(length(a), "\n"); + } +%} +-- End -- + +-- Expect stdout -- +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +-- End -- |