fix: reject string schemas that mix pattern/format with length bounds (#49996)
Signed-off-by: Yufeng He <40085740+he-yufeng@users.noreply.github.com>
This commit is contained in:
@@ -14,6 +14,12 @@ pytestmark = pytest.mark.cpu_test
|
||||
def unsupported_string_schemas():
|
||||
return [
|
||||
{"type": "string", "format": "non_existing_format"},
|
||||
# pattern/format is compiled but length bounds are silently dropped,
|
||||
# so the combination must be rejected instead of producing quietly
|
||||
# wrong output
|
||||
{"type": "string", "pattern": "^a+$", "maxLength": 2},
|
||||
{"type": "string", "pattern": "^a+$", "minLength": 3},
|
||||
{"type": "string", "format": "email", "maxLength": 10},
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -262,6 +262,20 @@ def has_xgrammar_unsupported_json_features(schema: dict[str, Any]) -> bool:
|
||||
):
|
||||
return True
|
||||
|
||||
# A string mixing a generative constraint (pattern or format) with
|
||||
# explicit length bounds. xgrammar compiles the pattern/format side
|
||||
# and silently drops minLength/maxLength from the grammar, so output
|
||||
# can violate the bound without any error surfacing. Verified against
|
||||
# the compiled EBNF: pattern/format grammars come out byte-identical
|
||||
# with and without the length keywords, while maxLength alone lowers
|
||||
# to {0, N} correctly.
|
||||
if (
|
||||
obj.get("type") == "string"
|
||||
and ("pattern" in obj or "format" in obj)
|
||||
and ("minLength" in obj or "maxLength" in obj)
|
||||
):
|
||||
return True
|
||||
|
||||
# Unsupported keywords for objects
|
||||
if obj.get("type") == "object" and any(
|
||||
key in obj for key in ("patternProperties", "propertyNames")
|
||||
|
||||
Reference in New Issue
Block a user