Catastrophic backtracking, minimal example
The smallest pattern that exhibits exponential backtracking. Three characters longer than the safe version and indistinguishable by eye.
/^(a+)+$/
Match a whole string consisting of one or more of (one or more of "a").
Do not run this against untrusted input — see below.
What to check
Dangerous
Catastrophic backtracking — this pattern can hang
(a+)+
A quantifier repeats a group that itself contains an unbounded quantifier over an overlapping character set. On input that ALMOST matches, the engine has exponentially many ways to split the text between the two quantifiers and must try all of them before it can report failure. A few dozen characters can take minutes of CPU, which makes this a denial-of-service vector if the pattern ever runs against untrusted input.
Fix: Remove one level of repetition. Usually the inner quantifier alone is enough: (a+)+ means the same thing as a+. Where the nesting is genuinely needed, make the inner part non-overlapping or use an atomic group in an engine that has one — JavaScript does not.
Note
Anchors match string ends, not line ends
Without the m flag, ^ and $ match only the very start and end of the input — not the start and end of each line. On multi-line input this is often not what was intended.
Fix: Add the m flag if the pattern should apply per line.
Step by step
^Anchor to the start of the input.
(a+)+Match one or more of (one or more of "a").
$Anchor to the end of the input.
Details
- Capture groups
- 1
- Flags
- None set
Check your own pattern
Paste one on the home page, or call the API or MCP server. This page is also available as markdown.