The regex-to-grammar converter in _visit_pattern() crashes with SIGSEGV
when a JSON schema "pattern" field contains a non-capturing group (?:...).
Root cause: when the parser sees '(' followed by '?', it pushes a warning
but does not advance past '?:'. The recursive transform() call then
interprets '?' as a quantifier and calls seq.back() on an empty vector,
causing undefined behavior.
This commonly occurs when serving OpenAI-compatible tool calls from
clients that include complex regex patterns in their JSON schemas (e.g.,
date validation patterns like ^(?:(?:\d\d[2468][048]|...)-02-29|...)$).
The fix:
- Skip '?:' after '(' to treat non-capturing groups as regular groups
- For unsupported syntax (?=, ?!, etc.), skip to matching ')' safely,
handling escaped characters to avoid miscounting parenthesis depth
- Adjust the ')' unbalanced-parentheses check using direct char
comparisons instead of substr
- Add test cases for non-capturing groups (C++ only, as the JS/Python
implementations do not yet support this syntax)
|
||
|---|---|---|
| .. | ||
| jinja | ||
| arg.cpp | ||
| arg.h | ||
| base64.hpp | ||
| build-info.cpp.in | ||
| chat-auto-parser-generator.cpp | ||
| chat-auto-parser-helpers.cpp | ||
| chat-auto-parser-helpers.h | ||
| chat-auto-parser.h | ||
| chat-diff-analyzer.cpp | ||
| chat-peg-parser.cpp | ||
| chat-peg-parser.h | ||
| chat.cpp | ||
| chat.h | ||
| CMakeLists.txt | ||
| common.cpp | ||
| common.h | ||
| console.cpp | ||
| console.h | ||
| debug.cpp | ||
| debug.h | ||
| download.cpp | ||
| download.h | ||
| hf-cache.cpp | ||
| hf-cache.h | ||
| http.h | ||
| json-partial.cpp | ||
| json-partial.h | ||
| json-schema-to-grammar.cpp | ||
| json-schema-to-grammar.h | ||
| llguidance.cpp | ||
| log.cpp | ||
| log.h | ||
| ngram-cache.cpp | ||
| ngram-cache.h | ||
| ngram-map.cpp | ||
| ngram-map.h | ||
| ngram-mod.cpp | ||
| ngram-mod.h | ||
| peg-parser.cpp | ||
| peg-parser.h | ||
| preset.cpp | ||
| preset.h | ||
| reasoning-budget.cpp | ||
| reasoning-budget.h | ||
| regex-partial.cpp | ||
| regex-partial.h | ||
| sampling.cpp | ||
| sampling.h | ||
| speculative.cpp | ||
| speculative.h | ||
| unicode.cpp | ||
| unicode.h | ||