Skip to content

Commit a4e340b

Browse files
committed
grammar : limit the number of alternatives
1 parent 4da6337 commit a4e340b

3 files changed

Lines changed: 17 additions & 1 deletion

File tree

‎src/llama-grammar.cpp‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <set>
1111
#include <stdexcept>
1212

13+
#define MAX_ALTERNATE_THRESHOLD 2000
1314
#define MAX_REPETITION_THRESHOLD 2000
1415
//
1516
// helpers
@@ -444,6 +445,9 @@ const char * llama_grammar_parser::parse_alternates(
444445
llama_grammar_rule rule;
445446
const char * pos = parse_sequence(src, rule_name, rule, is_nested);
446447
while (*pos == '|') {
448+
if (++n_alternates > MAX_ALTERNATE_THRESHOLD) {
449+
throw std::runtime_error("number of grammar alternatives exceeds sane defaults, please reduce the number of alternatives");
450+
}
447451
rule.push_back({LLAMA_GRETYPE_ALT, 0});
448452
pos = parse_space(pos + 1, true);
449453
pos = parse_sequence(pos, rule_name, rule, is_nested);
@@ -1527,4 +1531,3 @@ void llama_grammar_accept_token(struct llama_grammar & grammar, llama_token toke
15271531
throw std::runtime_error("Unexpected empty grammar stack after accepting piece: " + piece + " (" + std::to_string(token) + ")");
15281532
}
15291533
}
1530-

‎src/llama-grammar.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ struct llama_grammar_parser {
8888
std::map<std::string, uint32_t> symbol_ids;
8989

9090
llama_grammar_rules rules;
91+
size_t n_alternates = 0;
9192

9293
llama_grammar_parser(const struct llama_vocab * vocab = nullptr) : vocab(vocab) {}
9394

‎tests/test-grammar-parser.cpp‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,20 @@ static void verify_failure(const char * grammar_bytes) {
139139
assert(result.rules.empty() && "should have failed");
140140
}
141141

142+
static std::string grammar_with_alternates(size_t n_alternates) {
143+
std::string grammar = "root ::= \"a\"";
144+
for (size_t i = 0; i < n_alternates; ++i) {
145+
grammar += " | \"a\"";
146+
}
147+
return grammar;
148+
}
149+
142150
int main()
143151
{
152+
verify_failure(
153+
grammar_with_alternates(2001).c_str()
154+
);
155+
144156
verify_failure(R"""(
145157
root ::= "a"{,}"
146158
)""");

0 commit comments

Comments
 (0)