Commit Graph
7 Commits
Author SHA1 Message Date
BFlat 0f2225fe9c Merge pull request #2161 from Barzabel/fix/2124-2125-expr-nesting
expr: bound runtime parser and native recursion depth (#2124, #2125)
2026-10-30 01:19:11 +07:00
skylar taylor-barrick 69b9ce2bd1 M0.37: reconcile shared docking and qualify migration follow-up 2026-10-26 06:47:07 +01:00
Dylan M. Taylor 23f11ab7cf expr: bound rewrite expansion and preserve assignment targets (#2195)
* expr: bound rewrite expansion and preserve assignment targets

* expr: bound rewritten output size and rewrite computed assignment targets
2026-10-23 09:14:49 -04:00
Barzabel 6686cc75ca fix(expr): bound runtime parser and native recursion depth (#2124, #2125)
eval, Function and the generator/async function constructors now check the nesting of their source like the expression text. join, toLocaleString, flat and JSON.stringify check the run's stack use per level, results nested past the detached levels become [object], and Proxy/Reflect are no longer available to expressions. Each of these overflowed the stack and aborted the app.
2026-10-22 20:28:38 +03:00
vangel76andClaude Opus 5.5 9da66d9063 #786: fuzz expressions; fix the overflows, hangs and panic it found
Problem: expression text is input we don't control, and nothing fuzzed the
expression parser and evaluator. A seeded mutation fuzzer found stack
overflows (a few hundred `?:`/`=>`/`if`, a few thousand `.`/`<`/`()` links,
75 nested template substitutions or regex groups, a chain inside one
template), hangs (an expression reading its own layer's transform nested
2^16 times; fanning-out reads; 10M-iteration loops re-run per read; loops
calling looping functions), an i64 overflow panic in wiggle noise, and NaN
path vertices tripping the rasterizer's clipping assertion.

Fix: a dependency-free seeded fuzzer (crates/expr/src/tests/fuzz.rs: real
AE-style seeds, char/token mutations, worker thread with a 2 MiB stack,
catch_unwind, deadline, env vars for long runs); a weighted nesting
estimate covering chains without brackets and template/regex insides;
cycle detection per (property, time, text); a per-evaluation budget of
20 000 script runs and 5 s (runs are interrupted through boa's budgeted
evaluation; native only); loop limit 1M; wrapping noise lattice indices;
non-finite path results rejected. Each fix has a regression test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 14:40:03 +02:00
Brandon ThomasandClaude Opus 5.5 fc8fea031c Never crash: reject deeply nested expressions instead of overflowing the stack
An expression nested about 60 brackets deep overflowed the stack of a 2 MiB thread in the
JavaScript parser (release and debug; ~200 levels on 8 MiB), which aborts the whole app: it
can't be caught. The array-maths rewrite also nests one call per arithmetic operator, so a long
sum went the same way, and the rewriter itself recursed per bracket. rewrite() now measures the
nesting (brackets plus chains of prefix operators) before and after rewriting and turns an
expression deeper than MAX_NESTING (32) into a RangeError; check_syntax reports the same error.
Also replaces the unreachable!() in the bracket-tree builder with a let-chain, and denies the
panic lints in the crate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 13:22:36 -04:00
Brandon ThomasandClaude Opus 5.5 4ce50e00a0 M8: expressions engine (boa) with AE object model
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:39:02 -04:00