fix(schema): make hoisted component names JSON-Pointer safe and hash strictly - #383
Conversation
Scope widened after review (please re-review)The original commit sanitized only inside hoist_inline_defs({"$defs": {"Order/Item": {...}}, "properties": {"x": {"$ref": "#/$defs/Order/Item"}}}, {})
# before: component key 'Order/Item', ref '#/components/schemas/Order/Item' (unresolvable)New commit moves sanitization to This PR now closes #379 (JSON-Pointer safety, all paths) and #385 (strict |
There was a problem hiding this comment.
Pull request overview
This PR hardens schema hoisting so generated #/components/schemas/{name} references remain JSON-Pointer safe (no raw / or ~ in component names), and makes anonymous-schema hashing deterministic by requiring strict JSON serialization.
Changes:
- Sanitize hoisted component names centrally in
_resolve_name_collision()to prevent JSON-Pointer breakage across hoisting paths. - Make
_schema_short_hash()strict (nodefault=str, canonical separators) so non-JSON-serializable schemas raiseTypeError. - Add regression tests for
/and~sanitization, sanitized-name collisions, strict-hash failures, and the default$defshoisting path.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/azure_functions_openapi/utils.py |
Adds centralized component-name sanitization and strict canonical hashing for anonymous schema naming. |
tests/test_hoist_flat.py |
Adds tests validating JSON-Pointer-safe component names, collision aliasing, strict hashing behavior, and default $defs path sanitization. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| # Sanitize first so JSON-Pointer-unsafe characters (``/``, ``~``) can never | ||
| # reach a ``#/components/schemas/<name>`` reference, regardless of which | ||
| # hoisting path (``$defs``, model class, or flat schema) supplied the name. | ||
| name = _sanitize_component_name(name) |
|
Addressed Copilot review: removed the unreachable duplicate |
Delete the unreachable duplicate 'return name' in _resolve_name_collision and add a regression test asserting the model hoisting path (model_to_schema) sanitizes a '/'-bearing model name and rewrites the root $ref to the resolvable component key.
ac7a90a to
4171935
Compare
Summary
/and~never leak into#/components/schemas/{name}refs (JSON-Pointer safe), using_sanitize_component_name._schema_short_hashstrict: serialize withjson.dumps(schema, sort_keys=True, separators=(",", ":"))and drop thedefault=strfallback so non-JSON-serializable schemas raiseTypeErrorinstead of silently producing unstable hashes.Acceptance
/or~are sanitized (e.g.Order/Item->Order_Item).TypeError.make check-allgreen (coverage >= 95%).Closes #379