Skip to content

fix: bound plain-text runs in parse_prompt_attention regex - #1919

Open
fszontagh wants to merge 2 commits into
leejet:masterfrom
fszontagh:fix/prompt-attention-regex-stack
Open

fix: bound plain-text runs in parse_prompt_attention regex#1919
fszontagh wants to merge 2 commits into
leejet:masterfrom
fszontagh:fix/prompt-attention-regex-stack

Conversation

@fszontagh

Copy link
Copy Markdown
Contributor

Summary

parse_prompt_attention lexes the prompt with an unbounded plain-text alternative. libstdc++'s std::regex recurses once per matched character, so a prompt of a few tens of kilobytes overflows the stack and segfaults before tokenization.

Bound the run length. Splitting a long run is safe because the function's final pass merges adjacent segments of equal weight, and B is excluded from the character class, so a chunk boundary can never fall inside a BREAK.

Related Issue / Discussion

None.

Additional Information

A 45KB prompt exits 139 (SIGSEGV) during tokenization before the change and completes normally after it.

Parsing results are unchanged: comparing old and new output across weighted parentheses, nested ((...)), [...], escaped \(, multiple BREAKs, BREAKING and bare B, bare colons, the empty string, multi-byte UTF-8, and a 21KB run both bare and inside (...:1.3), every case is byte-identical.

Checklist

@leejet leejet left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

The plain-text repetition is bounded now, but the same stack-overflow path still exists in the weight alternative: :([+-]?[.\d]+)\) contains another unbounded +.

With libstdc++ (g++ 14.2, default 8 MiB stack), the PR still segfaults for e.g.:

":" + std::string(30000, '1')

A closing ) is not required: the regex recursively consumes the digit run while attempting the weight alternative before falling back to the literal : alternative.

Could we bound the numeric run as well (to a realistic float length), or avoid unbounded std::regex repetitions in this lexer entirely? We should also make sure oversized/invalid weights cannot terminate through std::stof.

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