Skip to content

Pattern compilation allocates 14+ GB and runs minutes before "exceeds complexity limits" when a counted repetition overlaps a preceding repeat #555

Description

@developerinlondon

Repro (ugrep 7.8.3, master 8cda03e, Linux x86_64)

ugrep -G -o '"content":"[^"]*coder[^"]\{0,300\}' /dev/null

No input needed (/dev/null). Compilation runs ~95 s and reaches 14.3 GB max RSS before finally reporting exceeds complexity limits. Under a tighter ulimit -v it dies earlier with std::bad_alloc. -U reduces the growth ~3x (UTF-8 expansion of [^"] amplifies it) but does not prevent it.

Minimal shape: a counted repetition that overlaps a preceding repeat —

ugrep -G '[^"]*coder[^"]\{0,100\}' /dev/null   # same blowup
ugrep -G 'coder[^"]\{0,300\}' /dev/null        # fine without the leading [^"]*

Mechanism

The DFA for this shape genuinely explodes (the automaton must track every candidate iteration count of the trailing repeat for every match start admitted by the preceding [^"]*). The existing guard vno_ > DFA::MAX_STATES (≈5.57M states) does fire — but only after minutes, because each of those states carries a positions vector with hundreds of iteration-tagged entries, i.e. memory grows ~2.5 KB per state while the limit only counts states.

Measured Σ pos.size() over all DFA states:

Pattern positions
104k-word dictionary via -f ~1 (tree DFA)
500-word alternation + [a-z]* suffix 5.5k
[0-9]{1,4096} 8.2k
email/UUID/IP/base64 regexes 37–1.5k
the pathological pattern above >32M and climbing

Impact

Claude Code (Anthropic's agentic CLI) bundles ugrep 7.5.0 as its grep replacement, so machine-generated patterns hit this in the wild: one such pattern grew to 11 GB and pushed a 125 GB host into memory-pressure thrash, freezing sibling processes (anthropics/claude-code#83342).

Proposed fix

PR follows: track accumulated positions stored in DFA states and raise the existing exceeds complexity limits error when the total passes a DFA::MAX_POSITIONS cap (4M — ~500x above the heaviest legitimate pattern measured). The pathological pattern then fails in 0.59 s at 155 MB with the same user-visible error, and make check passes.

Activity

  1. added a commit that references this issue on Aug 3, 2026
    7a1dc4d
  2. added a commit that references this issue on Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    patchA patch to fix an issue

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions