Skip to content

Resolve same-named schemas from different files as distinct components (fixes #2333)#2349

Open
seonwooj0810 wants to merge 1 commit into
swagger-api:masterfrom
seonwooj0810:fix/issue-2333-same-name-external-ref-collision
Open

Resolve same-named schemas from different files as distinct components (fixes #2333)#2349
seonwooj0810 wants to merge 1 commit into
swagger-api:masterfrom
seonwooj0810:fix/issue-2333-same-name-external-ref-collision

Conversation

@seonwooj0810

Copy link
Copy Markdown

Fixes #2333

Problem

When parsing a spec with resolve: true where two schemas in different files share the same name, both references collapse into the first model. In the issue's reproducer, SomeItem (→ inventory.yaml#/components/schemas/Pet, has name) and Pet (→ pets.yaml#/components/schemas/Pet, has id) both end up pointing at inventory's Pet.

Root cause

ExternalRefProcessor.finalNameRec decides which name a freshly resolved external schema gets. When the candidate name is already taken by an entry that still carries a $ref (an unresolved external placeholder, e.g. the sibling Pet component pointing at pets.yaml), the code unconditionally treated that slot as free and reused the name — then addSchemas(newRef, schema) overwrote the placeholder. The distinct second schema was lost.

Fix

A $ref placeholder slot is only safe to reuse when it targets the same reference currently being resolved. The incoming $ref is now threaded into finalNameRec; if the existing placeholder points to a different target, resolution falls through to the next suffixed name (Pet_1) instead of clobbering it. This is the conservative direction — a mismatch only ever produces an extra suffixed name, never data loss.

Result on the reproducer

SomeItem -> { name }     (inventory.yaml Pet)
Pet      -> { id }       (pets.yaml Pet)
Pet_1    -> { name }

SomeItem correctly carries name and Pet correctly carries id.

Test evidence

  • Added Issue2333Test with the issue's three-file reproducer asserting the two Pet schemas resolve distinctly. Passes.
  • Full swagger-parser-v3 module suite: 609 tests, 0 failures, 0 errors (run with -Dmaven.javadoc.skip=true; the offline javadoc fetch and the unrelated swagger-parser-safe-url-resolver PermittedUrlsCheckerTest failures are pre-existing JDK 25 environment issues, not related to this change).

Verification done

  1. No in-flight PR (gh pr list search for the issue/keywords — none open); 2. no self-claim in the thread; 3. code-focused (.java); 4. reproduced the bug on master, confirmed the fix flips the behavior; 5. confirmed root symbol finalNameRec/processRefToExternalSchema still present on master; 6. n/a (no parent epic).

When resolving with resolveFully/resolve, an external $ref whose target
shares a name with another, not-yet-resolved external $ref placeholder
caused the placeholder to be silently overwritten. ExternalRefProcessor's
finalNameRec treated any existing schema that still carried a $ref as a
free slot, so two distinct files defining e.g. 'Pet' collapsed into one.

Only reuse the existing name when the placeholder $ref targets the same
reference being resolved; otherwise fall through to a suffixed name.

Fixes swagger-api#2333
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Parser confuses referenced models with same name

1 participant