ik_llama_opt/tests
firecoperana 9ad8b8c6db
common/grammar: fix grammar parsing issues to prevent stack overflow and hangs (#1822)
* grammar: Fix grammar root symbol check (#19761)

* grammar: fix bad check for root symbol, correct error logging

* add tests to demonstrate root symbol check failure
# Conflicts:
#	tests/test-grammar-integration.cpp

* common/grammar: fix grammar parsing issues to prevent stack overflow and hangs (#18604)

* grammar: add test case for nullable symbol loop

Reproduce stack overflow (or OOM) with ( [x]* )* found while adding
GBNF support to ripgrep-edit.

llama-server reproducer:

curl \
  -X POST \
  -d '{
    "messages": [{ "role": "user", "content": "write yes" }],
    "grammar": "root ::= ( [x]* )*"
  }' \
  -H "Content-Type: application/json" \
  http://localhost:8811/v1/chat/completions

* grammar: prevent stack overflow with nullable symbol loop

Fix a potential stack overflow in llama_grammar_advance_stack that
could occur when processing grammars with nullable symbols that lead
to infinite derivations of empty strings. The fix introduces cycle
detection by tracking visited stacks to prevent infinite recursion.

rg-edit regexp: llama_grammar_advance_stack
rg-edit extra-args: -A20
rg-edit directive: """Rewrite: fix the following segfault:

[..]
 Testing segfault. Grammar:
            root ::= ( [x]* )*

            root ::= ( [x]* )*

Segmentation fault         build/bin/test-grammar-integration"""

gptel-context:
(("~/llama.cpp/src/llama-grammar.cpp")
 ("~/llama.cpp/tests/test-grammar-integration.cpp")
 ("~/llama.cpp/grammars/./list.gbnf")
 ("~/llama.cpp/grammars/./json_arr.gbnf")
 ("~/llama.cpp/grammars/./json.gbnf")
 ("~/llama.cpp/grammars/./japanese.gbnf")
 ("~/llama.cpp/grammars/./english.gbnf")
 ("~/llama.cpp/grammars/./chess.gbnf")
 ("~/llama.cpp/grammars/./c.gbnf")
 ("~/llama.cpp/grammars/./arithmetic.gbnf")
 ("~/llama.cpp/grammars/./README.md"))

* grammar: convert recursive llama_grammar_advance_stack to iterative

This change converts the function to an iterative approach using
explicit stacks, which prevents deep recursion and eliminates the risk
of stack overflow.

rg-edit regexp: llama_grammar_advance_stack
rg-edit extra-args: -A30
rg-edit directive: """Rewrite: fix the following segfault:

[..]
 Testing segfault. Grammar:
            root ::= ( [x]* )*

            root ::= ( [x]* )*

Segmentation fault         build/bin/test-grammar-integration

convert from recursive to interactive"""

gptel-context:
(("~/llama.cpp/src/llama-grammar.cpp")
 ("~/llama.cpp/tests/test-grammar-integration.cpp")
 ("~/llama.cpp/grammars/./list.gbnf")
 ("~/llama.cpp/grammars/./json_arr.gbnf")
 ("~/llama.cpp/grammars/./json.gbnf")
 ("~/llama.cpp/grammars/./japanese.gbnf")
 ("~/llama.cpp/grammars/./english.gbnf")
 ("~/llama.cpp/grammars/./chess.gbnf")
 ("~/llama.cpp/grammars/./c.gbnf")
 ("~/llama.cpp/grammars/./arithmetic.gbnf")
 ("~/llama.cpp/grammars/./README.md"))

v2: Added a `std::set` to perform tree-based lookups with O(N log N)
complexity. Testing with a parallel run of `test-grammar-integration`
shows a double-digit percentage increase in runtime. An
`unordered_set` with O(1) hashing was also evaluated, but the overhead
of constructing hash keys from pointers made it significantly slower
than the rbtree implementation that only requires an ordering
operator. The performance regression in the test suite appears
justified by the overall reduction in algorithmic complexity.

Co-developed-by: Piotr Wilkin (ilintar) <piotr.wilkin@syndatis.com>

* grammar: add test case for hang in repetition grammar processing

This commit adds a new test case to the grammar integration tests that
specifically targets a hang scenario in the repetition grammar parser
found while adding GBNF support to ripgrep-edit.

llama-server reproducer:

curl \
  -X POST \
  -d '{
    "messages": [{ "role": "user", "content": "write yes" }],
    "grammar": "root ::= (([^x]*){0,99}){0,99}"
  }' \
  -H "Content-Type: application/json" \
  http://localhost:8811/v1/chat/completions

* grammar: add repetition threshold check

The change introduces a maximum repetition threshold to avoid
excessive rule expansion during grammar parsing. When parsing
repetition patterns like {m,n}, the parser now calculates the
potential number of rules that would be generated and throws an error
if the product of previous rules and new rules exceeds the threshold.

A test case was added to verify the threshold is properly enforced for
deeply nested repetition patterns that would otherwise cause hangs.

---------

Co-authored-by: Asbjørn Olling <asbjornolling@gmail.com>
Co-authored-by: Andrea Arcangeli <aarcange@redhat.com>
2026-05-19 08:36:49 +03:00
..
peg-parser Autoparser - complete refactoring of parser architecture (#1376) 2026-04-22 10:04:13 +02:00
.gitignore common : introduce composable PEG parser combinators for chat parsing and new jinja template engine (#1369) 2026-03-09 11:03:33 +01:00
CMakeLists.txt Autoparser - complete refactoring of parser architecture (#1376) 2026-04-22 10:04:13 +02:00
get-model.cpp
get-model.h
run-json-schema-to-grammar.mjs json-schema-to-grammar improvements (+ added to server) (#5978) 2024-03-21 11:50:43 +00:00
test-autorelease.cpp spec : add self speculative decoding, ngram and refactor (#1261) 2026-02-13 19:04:55 +01:00
test-backend-ops.cpp Update mtmd to improve accuracy of M-RoPE (#993) 2025-11-29 07:27:15 +01:00
test-c.c Nomic Vulkan backend (#4456) 2024-01-29 15:50:50 -05:00
test-chat-auto-parser.cpp AutoParser: improve reasoning budget and handling of space/newline in tool calls (#1819) 2026-05-19 08:34:19 +03:00
test-chat-peg-parser.cpp Autoparser - complete refactoring of parser architecture (#1376) 2026-04-22 10:04:13 +02:00
test-chat-template.cpp Autoparser - complete refactoring of parser architecture (#1376) 2026-04-22 10:04:13 +02:00
test-chat.cpp AutoParser: improve reasoning budget and handling of space/newline in tool calls (#1819) 2026-05-19 08:34:19 +03:00
test-double-float.cpp Merge mainline llama.cpp (#3) 2024-07-27 07:55:01 +02:00
test-function-calls.cpp Fix for Deepseek r1 parsing (#676) 2025-08-08 13:56:44 +03:00
test-grad0.cpp ggml : refactor rope norm/neox (#7634) 2024-06-05 11:29:20 +03:00
test-grammar-integration.cpp common/grammar: fix grammar parsing issues to prevent stack overflow and hangs (#1822) 2026-05-19 08:36:49 +03:00
test-grammar-llguidance.cpp Tool calls support from mainline (#723) 2025-09-01 08:38:49 +03:00
test-grammar-parser.cpp common/grammar: fix grammar parsing issues to prevent stack overflow and hangs (#1822) 2026-05-19 08:36:49 +03:00
test-jinja.cpp Autoparser - complete refactoring of parser architecture (#1376) 2026-04-22 10:04:13 +02:00
test-json-partial.cpp common : introduce composable PEG parser combinators for chat parsing and new jinja template engine (#1369) 2026-03-09 11:03:33 +01:00
test-json-schema-to-grammar.cpp Autoparser - complete refactoring of parser architecture (#1376) 2026-04-22 10:04:13 +02:00
test-llama-grammar.cpp common/grammar: fix grammar parsing issues to prevent stack overflow and hangs (#1822) 2026-05-19 08:36:49 +03:00
test-model-load-cancel.cpp spec : add self speculative decoding, ngram and refactor (#1261) 2026-02-13 19:04:55 +01:00
test-opt.cpp code : normalize enum names (#5697) 2024-02-25 12:09:09 +02:00
test-peg-parser.cpp Autoparser - complete refactoring of parser architecture (#1376) 2026-04-22 10:04:13 +02:00
test-quantize-fns.cpp Merge mainline llama.cpp (#3) 2024-07-27 07:55:01 +02:00
test-quantize-perf.cpp Merge mainline llama.cpp (#3) 2024-07-27 07:55:01 +02:00
test-reasoning-budget.cpp Autoparser - complete refactoring of parser architecture (#1376) 2026-04-22 10:04:13 +02:00
test-regex-partial.cpp llama : add token matching support to llama-grammar (#1220) 2026-02-03 07:57:17 +02:00
test-rope.cpp Merge mainline llama.cpp (#3) 2024-07-27 07:55:01 +02:00
test-sampling.cpp Merge mainline - Aug 12 2024 (#17) 2024-08-12 15:14:32 +02:00
test-tokenizer-0.cpp spec : add self speculative decoding, ngram and refactor (#1261) 2026-02-13 19:04:55 +01:00
test-tokenizer-0.py py : logging and flake8 suppression refactoring (#7081) 2024-05-05 08:07:48 +03:00
test-tokenizer-0.sh tests : fix test-tokenizer-0.sh 2024-05-28 15:04:09 +03:00
test-tokenizer-1-bpe.cpp Server: refactor and rename functions (#1151) 2026-01-18 08:16:57 +02:00
test-tokenizer-1-spm.cpp Server: refactor and rename functions (#1151) 2026-01-18 08:16:57 +02:00
test-tokenizer-random.py Merge mainline llama.cpp (#3) 2024-07-27 07:55:01 +02:00
testing.h common : introduce composable PEG parser combinators for chat parsing and new jinja template engine (#1369) 2026-03-09 11:03:33 +01:00