Conversation
7 of 12 tasks
Collaborator
Amoifr
force-pushed
the
fix-949-schema-id-discovery
branch
from
September 16, 2026 07:29
545b1f0 to
8a6ba78
Compare
Contributor
Author
|
Thanks for the quick fix in #956, and for the heads-up! Rebased on main. One thing worth mentioning: the two |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #949
Problem
SchemaStoragewalks a document looking forid/$idso it can register subschemas under their canonical URI. It descends into every member it meets, so an$idwritten in a position that holds data rather than a schema gets registered as though it identified a schema. When that value collides with a real$idelsewhere in the document, the fake one can win, and a$refto that URI then resolves to the wrong schema.That is exactly what
unknownKeyword.jsonin the official suite pins down: an$idburied under an unknown keyword must not shadow the real one.Cause
scanMembersForSubschemas()skippedenumandconstby name. That covers two data positions out of many:default,examplesand any unknown keyword were still descended into.Fix
Instead of listing the positions to avoid, which is open ended, the scanner now only descends into positions that actually hold schemas. Two classification lists sit beside the existing
SCHEMA_MAP_KEYWORDS:SCHEMA_KEYWORDS, whose value is a schema (not,if,additionalProperties, and so on)SCHEMA_ARRAY_KEYWORDS, whose value is a list of schemas (allOf,anyOf,prefixItems, and so on)Everything else is data, and an
idinside it identifies nothing.Members of a schema map (
properties,$defs,definitions, ...) remain schemas whatever their name, which is what the existing$parentPropertycheck already guaranteed: a subschema legitimately namedenumis still traversed.The classification is deliberately draft agnostic, since
SchemaStorageis never told which dialect it is reading. A keyword counts if it holds schemas in any draft. That is also the safer direction: treating a keyword unknown to the current draft as a schema position is simply the behaviour every keyword had before.Tests
Six cases added to
subschemaRegistrationProvider(). Four fail without the source change (default,examples, an unknown keyword holding a list, an unknown keyword holding a map). The remaining two guard against over narrowing in the other direction, checking that anidundernotand under anitemstuple is still registered.The six now obsolete
unknownKeyword.jsonentries inshouldNotYieldTest()are removed.Notes
expandRefs()carries the sameenum/constspecial case. I left it untouched: the fixture does not exercise it, and measuring confirmed the scanner change alone is sufficient. Glad to align the two walkers in a follow up if you would prefer they agree.One caveat on how far I could verify this.
JsonSchemaTestSuiteTestcurrently yields no tests at all, because the upstream suite added atests/v1/directory thatDraftIdentifiers::fromConstraintName()rejects, and PHPUnit reports that as a warning while still exiting 0. I opened #953 about it. To exercise theunknownKeywordcases here I skippedv1locally, which is not part of this PR. With the suite unblocked that way, this change takes the failure count from 364 down to 354, repairing 6 suite cases plus the 4 new unit cases, and breaking none.PHPStan reports no errors. Thanks for the library, and for the very readable
SchemaStorage, which made this one pleasant to chase. 🙂