Skip to content

Commit 79967ec

Browse files
authored
grammar : use int64_t to avoid int overflows in int schema to grammar conversion logic (ggml-org#16626)
1 parent ceff6bb commit 79967ec

File tree

2 files changed

+36
-12
lines changed

2 files changed

+36
-12
lines changed

common/json-schema-to-grammar.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ static std::string build_repetition(const std::string & item_rule, int min_items
4141
return result;
4242
}
4343

44-
static void _build_min_max_int(int min_value, int max_value, std::stringstream & out, int decimals_left = 16, bool top_level = true) {
45-
auto has_min = min_value != std::numeric_limits<int>::min();
46-
auto has_max = max_value != std::numeric_limits<int>::max();
44+
static void _build_min_max_int(int64_t min_value, int64_t max_value, std::stringstream & out, int decimals_left = 16, bool top_level = true) {
45+
auto has_min = min_value != std::numeric_limits<int64_t>::min();
46+
auto has_max = max_value != std::numeric_limits<int64_t>::max();
4747

4848
auto digit_range = [&](char from, char to) {
4949
out << "[";
@@ -159,7 +159,7 @@ static void _build_min_max_int(int min_value, int max_value, std::stringstream &
159159
if (has_min) {
160160
if (min_value < 0) {
161161
out << "\"-\" (";
162-
_build_min_max_int(std::numeric_limits<int>::min(), -min_value, out, decimals_left, /* top_level= */ false);
162+
_build_min_max_int(std::numeric_limits<int64_t>::min(), -min_value, out, decimals_left, /* top_level= */ false);
163163
out << ") | [0] | [1-9] ";
164164
more_digits(0, decimals_left - 1);
165165
} else if (min_value == 0) {
@@ -194,7 +194,7 @@ static void _build_min_max_int(int min_value, int max_value, std::stringstream &
194194
}
195195
digit_range(c, c);
196196
out << " (";
197-
_build_min_max_int(std::stoi(min_s.substr(1)), std::numeric_limits<int>::max(), out, less_decimals, /* top_level= */ false);
197+
_build_min_max_int(std::stoll(min_s.substr(1)), std::numeric_limits<int64_t>::max(), out, less_decimals, /* top_level= */ false);
198198
out << ")";
199199
if (c < '9') {
200200
out << " | ";
@@ -216,7 +216,7 @@ static void _build_min_max_int(int min_value, int max_value, std::stringstream &
216216
_build_min_max_int(0, max_value, out, decimals_left, /* top_level= */ true);
217217
} else {
218218
out << "\"-\" (";
219-
_build_min_max_int(-max_value, std::numeric_limits<int>::max(), out, decimals_left, /* top_level= */ false);
219+
_build_min_max_int(-max_value, std::numeric_limits<int64_t>::max(), out, decimals_left, /* top_level= */ false);
220220
out << ")";
221221
}
222222
return;
@@ -925,17 +925,17 @@ class SchemaConverter {
925925
int max_len = schema.contains("maxLength") ? schema["maxLength"].get<int>() : std::numeric_limits<int>::max();
926926
return _add_rule(rule_name, "\"\\\"\" " + build_repetition(char_rule, min_len, max_len) + " \"\\\"\" space");
927927
} else if (schema_type == "integer" && (schema.contains("minimum") || schema.contains("exclusiveMinimum") || schema.contains("maximum") || schema.contains("exclusiveMaximum"))) {
928-
int min_value = std::numeric_limits<int>::min();
929-
int max_value = std::numeric_limits<int>::max();
928+
int64_t min_value = std::numeric_limits<int64_t>::min();
929+
int64_t max_value = std::numeric_limits<int64_t>::max();
930930
if (schema.contains("minimum")) {
931-
min_value = schema["minimum"].get<int>();
931+
min_value = schema["minimum"].get<int64_t>();
932932
} else if (schema.contains("exclusiveMinimum")) {
933-
min_value = schema["exclusiveMinimum"].get<int>() + 1;
933+
min_value = schema["exclusiveMinimum"].get<int64_t>() + 1;
934934
}
935935
if (schema.contains("maximum")) {
936-
max_value = schema["maximum"].get<int>();
936+
max_value = schema["maximum"].get<int64_t>();
937937
} else if (schema.contains("exclusiveMaximum")) {
938-
max_value = schema["exclusiveMaximum"].get<int>() - 1;
938+
max_value = schema["exclusiveMaximum"].get<int64_t>() - 1;
939939
}
940940
std::stringstream out;
941941
out << "(";

tests/test-grammar-integration.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,30 @@ static void test_simple_grammar() {
301301
"0123",
302302
}
303303
);
304+
test_schema(
305+
"min 1 max 900719925474091",
306+
// Schema
307+
R"""({
308+
"type": "integer",
309+
"exclusiveMinimum": 0,
310+
"maximum": 900719925474091
311+
})""",
312+
// Passing strings
313+
{
314+
"1",
315+
"2",
316+
"10",
317+
"900719925474090",
318+
"900719925474091",
319+
},
320+
// Failing strings
321+
{
322+
"0",
323+
"01",
324+
"900719925474092",
325+
"9007199254740910",
326+
}
327+
);
304328
test_schema(
305329
"min -1 max 1",
306330
R"""({

0 commit comments

Comments
 (0)