mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-31 07:23:06 +08:00
Security review finding (#747): rn_first recursed into every split target (split_next/split_goto/loop/loop_split). `visited` stops cycles but not depth, so a flat runtime pattern with a long run of alternatives, such as new RegExp("(?:" + "|".repeat(n) + "x)"), chains one split per alternative and recursed once per alternative while the regex was being constructed (scr_re_native_build runs on every compile), before any subject is matched. Deep enough patterns could exhaust the C stack of the thread compiling them. The analysis is now iterative: split targets go on a heap worklist of nops + 1 entries allocated next to `visited`. Every op is processed once, so each split pushes at most one entry, and the accumulated first-byte set, empty-match and anchor flags do not depend on the visiting order. If the worklist cannot be allocated the native build fails and the regex keeps using libregexp, like the other native-build failures. No other function in scr_regex_native.h recurses on pattern structure. Tests: corpus 3139 constructs runtime patterns with 30,000-alternative runs (empty, consuming, word-bounded, capturing, nested-but-flat, global) and matches ASCII subjects; it matches Node in the plain and sanitized lanes.