Skip to content

fix: add maxDepth to stop deeply nested patterns overflowing the stack (CVE-2026-93687) - #86

Closed
mcris-roberto wants to merge 2 commits into
micromatch:masterfrom
mcris-roberto:fix/max-nesting-depth
Closed

mcris-roberto wants to merge 2 commits into
micromatch:masterfrom
mcris-roberto:fix/max-nesting-depth

Conversation

@mcris-roberto

@mcris-roberto mcris-roberto commented Oct 9, 2026 •

Copy link
Copy Markdown

Addresses #70 / GHSA-vfj7-8cjw-p6xm.

Deeply nested patterns that fit inside the default maxLength (e.g. '{'.repeat(4900) + 'a,b' + '}'.repeat(4900), about 9.8k chars) overflow the call stack in the recursive compile walker with RangeError: Maximum call stack size exceeded.

Change

  • Add options.maxDepth (default 256). It can lower the limit but not raise it above the default.
  • The parser throws a SyntaxError when brace/paren nesting exceeds it, the same way maxLength does. Nothing is silently reinterpreted.
  • compile, expand and stringify enforce the same limit while walking, so ASTs built by hand (which never go through parse) cannot overflow either.
  • README documents the option.

Tests

test/max-depth.js (new): deep balanced/unbalanced braces, deep parens, exact boundary (256 ok, 257 throws), options.maxDepth, cannot be raised, and hand-built ASTs through compile/expand/stringify. Full suite: 902 passing; the new depth tests fail without the lib/ changes.

Relation to existing PRs

Overlaps #78, #79 and #82, so feel free to take whichever design you prefer. In short: like #78 it throws and guards the walkers (but it adds the maxDepth option proposed in #77, and is smaller); like #79 it adds maxDepth with a 256 default (but it throws instead of keeping deeper input as literal text, and guards the walkers). It does not include #82's cycle detection or node-count cap.

Known limit: the default is fixed at 256 and cannot be raised, which could break someone who legitimately nests deeper. Patterns nested that deep are not realistic, but I'm happy to change the default or make it configurable.

🤖 Generated with Claude Code

Maricris Roberto and others added 2 commits October 9, 2026 10:35
…-2026-93687)

Adds options.maxDepth (default 1000, cannot be raised). Deeper input throws a
SyntaxError like maxLength does, instead of overflowing the recursive
compile/expand/stringify walkers.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… walkers

Hand-built ASTs bypass parse, so the recursive walkers now enforce the same
limit (CVE-2026-93687).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@mcris-roberto

mcris-roberto commented Oct 9, 2026 •

Copy link
Copy Markdown
Author

Apologies, I just saw the Issue #84: as "NOTHING TO FIX".

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