Skip to content

fix(autoInject): eliminate O(n²) stripComments and regex stack overflow (fixes failing ReDoS test)#2076

Open
JSap0914 wants to merge 1 commit into
caolan:masterfrom
JSap0914:fix/autoinject-stripcmments-redos
Open

fix(autoInject): eliminate O(n²) stripComments and regex stack overflow (fixes failing ReDoS test)#2076
JSap0914 wants to merge 1 commit into
caolan:masterfrom
JSap0914:fix/autoinject-stripcmments-redos

Conversation

@JSap0914

Copy link
Copy Markdown

The existing test autoInject > should not be subject to ReDoS (added in #1767) currently fails on master due to two issues introduced after the #1980 merge:

Root causes

1. stripComments is O(n²) for large inputs

The function builds the output string with character-by-character concatenation:

stripped += string[index]; // O(n) allocations for an n-character string

For the 'text/*'.repeat(1000000) test input (6 M chars) this takes ~1 second in V8, consuming most of the 2-second mocha timeout.

2. ARROW_FN_ARGS regex causes a stack overflow on very long strings

var ARROW_FN_ARGS = /^(?:async\s)?\s*(?:\(\s*)?((?:[^)=\s]\s*)*)(?:\)\s*)?=>/;

Applied to the same 6 M-character string (which contains no =>), V8's NFA regex engine enters deep recursive backtracking and throws:

RangeError: Maximum call stack size exceeded

Fix

stripComments – replace char-by-char concatenation with slice accumulation: push string.slice(segmentStart, index) only at comment boundaries and parts.join("") at the end. This makes the function O(n) and preserves identical semantics (verified against all existing tests including the multi-line and nested-comment cases added in #1767 and #1780).

parseParams – guard the ARROW_FN_ARGS regex with src.indexOf("=>") !== -1. Arrow functions must contain =>; skipping the regex for inputs that lack it prevents the stack overflow with no change in matching behaviour.

Verification

Before: 1 failing  – autoInject > should not be subject to ReDoS (timeout)
After:  690 passing, 0 failing

No existing test was modified.

AI-assisted contribution.

stripComments used character-by-character string concatenation
(stripped += string[index]) which is O(n²) in V8 for large inputs —
~1 second for a 6 M-character string.  Switch to slice-based
accumulation: collect non-comment slices into an array, push only at
comment boundaries, join at the end.  This reduces the cost to O(n).

Additionally, ARROW_FN_ARGS regex applied to a very long string with no
'=>' caused RangeError: Maximum call stack size exceeded due to deep
recursive NFA backtracking.  Arrow functions always contain '=>', so
guard the regex call with src.indexOf('=>') !== -1 to skip it entirely
for inputs that can never match.

Together these fix the failing test:
  autoInject > should not be subject to ReDoS

Fixes caolan#1975 regression introduced by caolan#1980.
Copilot AI review requested due to automatic review settings June 23, 2026 12:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants