views/spot/match.js's regexMatcher compiles new RegExp(jsBody) from the user URI fragment, then runs re.exec per line over every candidate file behind the regex: VIEW. The only ceiling is a whole-file 16 MiB gate — no per-line length cap and no time/step budget — so (a+)+$ against a long line hangs the single-threaded runtime. Native used a Thompson NFA (linear), so this is also a parity divergence; matchFlat (the spot backtracker) likewise has no guard. Method: Issues.
views/regex/regex.js:1-6 — the regex: verb is one line; it just
module.exports = require("../spot/search.js"), riding the shared scaffold.
views/spot/match.js:47 re = new RegExp(jsBody) where :45
jsBody = body.replace(…) and body is the user URI fragment — untrusted, backtracking JS-RegExp (catastrophic for (a+)+$).
:50-66 run(): splitLinesBytes then re.exec(lineText) per line, perfile — no per-line length cap, no step/time budget.
views/spot/search.js:273-274 whole-file SPOTBIG gate
if (bytes.length >= (1<<24)) return (16 MiB) — does NOT bound a single long line's backtracking.
:8 :37-40 notes native walked a Thompson NFA
(NFAu8Search, linear); the JS RegExp diverges on adversarial input.
views/spot/match.js:158 matchFlat — recursive backtracker
(:222 :243 :269 :311 :329 :376 recurse with no depth/step guard), so the structural spot mode is exposed to the same blowup.
regex: (and spot:) search over a hostile file cannot wedge the runtime:a per-line length cap and/or a step/time budget bounds the work.
regex:(a+)+$ (or spot analogue) over a long single-linefile completes within a wall-clock budget instead of hanging.
views/spot/search.js; keep the {,m}→{0,m} dialect
rewrite (:45) and the per-line first-match byte-span behavior.
grep_match_span); don't regress the
parity corpus. Scope: regexMatcher/matchFlat guards (+ a size cap).
wall-clock budget around re.exec; on overflow treat the line as no-match.
(a+)+, (a*)*) atcompile time so the worst exponentials never run.
matchFlat (bail → no-match on overflow);longer-term, port the bounded Thompson NFA for true linear parity.
test/js/regex/* (+ spot): regex:(a+)+$ over a longsingle-line file hangs today; assert it returns within a budget.
to regexMatcher; add the step guard to matchFlat.
portable budget; pick a bound that keeps the parity corpus green.
views/spot/match.js:47 re = new RegExp(jsBody) from the
untrusted URI fragment, no per-line cap / step budget; matchFlat:158 is still the uncapped recursive backtracker. Only ceiling remains the whole-file SPOTBIG gate in search.js.