Skip to content

fix: Rebase relative refs inside external path items only once (#2418) - #2419

Open
ericschlarmann wants to merge 1 commit into
swagger-api:masterfrom
ericschlarmann:fix-nested-path-item-relative-refs
Open

ericschlarmann wants to merge 1 commit into
swagger-api:masterfrom
ericschlarmann:fix-nested-path-item-relative-refs

Conversation

@ericschlarmann

Copy link
Copy Markdown

Pull Request

Description

Fixes a regression in 2.1.48. With the root document in a subdirectory, a relative schema or example $ref inside an external path item two directories down was rebased twice. ../../domain/sub/schemas.yaml became ../domain/domain/sub/schemas.yaml, and resolving it failed with Unable to load RELATIVE ref.

ExternalRefProcessor.processPathItem already rebases these refs onto the root document. PathsProcessor.updateRefs then resolved them again against the path item's file, and computePreprocessedRef only recognizes a rebased ref when it does not start with a dot or starts with ./. A rebased ref can start with ../ once the root document is not at the top.

ExternalRefProcessor now records the schemas and examples it rebased (an identity set, scoped to the processor instance PathsProcessor owns), and PathsProcessor.updateRefs leaves those alone. Every other ref takes the same path as before, so the existing computeRef / computePreprocessedRef tests are unchanged.

Fixes: #2418

Type of Change

  • 🐛 Bug fix
  • ✨ New feature
  • ♻️ Refactor (non-breaking change)
  • 🧪 Tests
  • 📝 Documentation
  • 🧹 Chore (build or tooling)

Checklist

  • I have added/updated tests as needed
  • I have added/updated documentation where applicable
  • The PR title is descriptive
  • The code builds and passes tests locally
  • I have linked related issues (if any)

Screenshots / Additional Context

New data-driven test PathsProcessorTest.testRefInPathItemBelowSubdirectoryEntryIsRebasedOnce with resources in src/test/resources/path-item-below-subdirectory-entry/: root documents in api/, path items in domain/sub/. It uses one root document per case, because the first ref that fails to load stops the resolution of every later one.

The seven cases that processPathItem rebases fail on master and pass with the fix:

  • a ../../domain/sub/ ref,
  • a ./ ref,
  • a bare schemas.yaml ref,
  • a ref into another directory (../../shared/),
  • a nested property ref,
  • a response example,
  • an operation parameter schema.

On master they come out as ../domain/domain/sub/schemas.yaml or ../domain/shared/schemas.yaml.

Two cases that only PathsProcessor rebases (a path-level parameter schema and a request body example) pass on both. They pin that every other ref is still rebased once.

Full build mvn test on JDK 17: all modules green.

Also checked against a larger real-world multi-file spec set with three root documents, generating with openapi-generator 7.26.0 and this build swapped in:

  • The root document at the top of the tree gives byte-identical output to stock 2.1.48.
  • The other two, including the one in a subdirectory (the failing case), give byte-identical output to stock 2.1.47.
  • With openapi-generator 7.27.0, the subdirectory root document generates without errors again.

ExternalRefProcessor.processPathItem rebases the relative schema and
example refs of an external path item onto the root document. Afterwards
PathsProcessor.updateRefs resolves the same refs again against the path
item's file. computePreprocessedRef skips a ref only when it does not
start with a dot or starts with "./". The second resolution is therefore
a no-op for an entry document at the root, and also for path items one
directory down. It can break once the rebased ref starts with "../":
with the entry in a subdirectory and the path item two directories down,
../../domain/sub/schemas.yaml becomes ../domain/domain/sub/schemas.yaml
("Unable to load RELATIVE ref"). Before 2.1.48 the unnormalized
concatenation of computeRelativeRef left
../domain/sub/../domain/sub/schemas.yaml, which the ".." fallback in
RefUtils.readExternalRef happened to recover.

ExternalRefProcessor now records the schemas and examples it rebased,
and PathsProcessor leaves those alone. Every other ref is rebased as
before.
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]: 2.1.48 rebases a relative $ref inside an external path item twice when the root document is in a subdirectory

1 participant