fix: harden composite input authoring

This commit is contained in:
lda
2026-08-14 12:01:44 +07:00 Verified
parent 4493b56ebe
commit 89e934e65b
13 changed files with 326 additions and 60 deletions
+27 -1
View File
@@ -48,6 +48,12 @@ _STRUCTURAL_KEYWORDS = frozenset(
"prefixItems",
"minItems",
"maxItems",
"minLength",
"maxLength",
"pattern",
"format",
"uniqueItems",
"multipleOf",
"minimum",
"maximum",
"exclusiveMinimum",
@@ -612,7 +618,7 @@ def _validate_schema_references(
raise ValueError(f"cyclic local schema reference {reference!r} at {label}")
context.active_refs.add(reference)
try:
resolved = _resolved_schema(schema, label=label, root_schema=root_schema)
resolved = _resolve_local_reference(root_schema, schema, label=label)
_validate_schema_references(
resolved,
root_schema=root_schema,
@@ -652,6 +658,26 @@ def _validate_schema_references(
label=f"{label}.prefixItems[{index}]",
context=context,
)
for key in ("allOf", "anyOf", "oneOf"):
branches = schema.get(key)
if isinstance(branches, list):
for index, child in enumerate(branches):
if isinstance(child, Mapping):
_validate_schema_references(
child,
root_schema=root_schema,
label=f"{label}.{key}[{index}]",
context=context,
)
for key in ("if", "then", "else"):
child = schema.get(key)
if isinstance(child, Mapping):
_validate_schema_references(
child,
root_schema=root_schema,
label=f"{label}.{key}",
context=context,
)
for key in ("$defs", "definitions"):
definitions = schema.get(key)
if isinstance(definitions, Mapping):
+15 -6
View File
@@ -160,12 +160,16 @@ def schema_location_is_explicit(
and part < len(current["prefixItems"])
):
return False
child = _array_item_schema(
current,
part,
label=label,
location=(*traversed, part),
)
try:
child = _array_item_schema(
current,
part,
label=label,
location=(*traversed, part),
)
except ValueError:
# Predicates remain total for invalid or unconstrained paths.
return False
else:
properties = current.get("properties")
if isinstance(properties, Mapping) and part in properties:
@@ -571,6 +575,11 @@ def _array_item_schema(
label: str,
location: Sequence[SchemaLocationPart],
) -> object:
if index < 0:
raise ValueError(
f"{label} array position {index} is negative at "
f"{_format_schema_location(location[:-1]) or label!r}"
)
schema_type = schema.get("type")
if schema_type is not None and schema_type != "array":
raise ValueError(