Test/fuzz normalizer - #299
Merged
Merged
Conversation
A base that carries a scheme but no path of its own ("a:", "smb://host")
leaves the joined path relative. Rendering that gives "scheme://path", which
promotes the path to an authority component: "a://some file.json" no longer
parses, and normalizing such a $ref panics instead of resolving it.
Anchor the joined path so that the rendered URI stays canonical.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
denormalizeRef rewrites a $ref when expansion stops on a circular reference. Four ways it could point the rewritten $ref at another document: - the base was cut off a $ref as a plain string prefix, so a sibling named spec.json.orig ended up rebased as ".orig" against the wrong folder; - a $ref to the folder holding the base collapsed to an empty $ref, which denotes the base document itself; - the query component was dropped, losing "?raw=true" and the like; - the userinfo component was dropped, losing credentials. rebase now cuts on path boundaries, and keeps a $ref absolute whenever a relative one could not carry the query or the credentials it needs. Its boolean is renamed isID, because the two callers mean different things by the URI they hand it: an "id" anchors a namespace, so a $ref below it rebases on the id itself, whereas a base is a document, so a $ref rebases on the folder holding it and only a $ref to that very document collapses to an empty $ref. Conflating the two is what produced the first two defects above. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
FuzzNormalizer walks arbitrary ($ref, base) pairs through normalizeBase, normalizeURI and denormalizeRef. It asserts that normalizing yields a parseable URI carrying a scheme, that normalizing twice changes nothing, and that denormalizing a canonical $ref yields a shorthand that normalizes back to it. That last property is skipped for URIs which jsonreference respells: turning a URI into a Ref lower-cases the host, drops a default port and re-derives the escapes, where the normalizer keeps the spelling it was handed. The corpus checked in under testdata holds the minimized inputs of the defects this target found, so they run as ordinary test cases. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
SchemaOrArray fell back on the single-schema form whenever the array was empty, so a schema carrying "items": [] was written back as "items": null - which is not a schema, and which reads back as no items at all. Marshal the array form whenever the array is there, empty or not. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
FuzzSwaggerRoundTrip unmarshals arbitrary JSON into Swagger, writes it back and reads it again, requiring the two renderings to agree. That covers the two dozen hand-written UnmarshalJSON methods a document lands on, several of which are union types switching on the shape of a value rather than on a discriminator: writing back is where one that guessed wrong shows up. The seeds aim at those union members rather than at coverage of the specification. The corpus checked in under testdata holds the minimized input that caught the empty "items" array. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
FuzzExpandSpec expands arbitrary documents, requiring that expansion terminates and that what it returns is still a document: an expansion that succeeds but leaves behind something we can no longer read corrupts the caller's spec silently. The document loader is stubbed, so the target reads no file and opens no socket. The stub answers every path with the same document, and that document holds a $ref back out to another one, so a remote $ref chains forever unless cycle detection and the expansion budget stop it. Seeds cover $refs in each position that accepts one, and cycles - direct, mutual, and through a remote document. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
A default port and an upper-case host are equivalent spellings of one authority. jsonreference normalizes both away when a URI becomes a Ref, whereas the normalizer keeps the spelling it was handed, and denormalizeRef compared the two against each other: a base of "https://example.com:443/spec.json" made every $ref look like it belonged to another host, so rebasing declined and left it absolute. Expanding an ordinary document, whose own $refs are all local, then yielded remote absolute $refs - the AbsoluteCircularRef behaviour, given to a caller who did not ask for it, on account of how the base was spelled. Canonicalize the base, and the schema id, before rebasing compares them. The new fixture holds two cycles sharing a node, which is what forces expansion to cut one of them with a $ref. Which node receives it depends on the order of the walk and is deliberately not asserted; that no remaining $ref leaves the document is. This addresses the authority. Path and fragment escaping are respelled by jsonreference too, and still differ. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #299 +/- ##
==========================================
+ Coverage 68.43% 68.77% +0.34%
==========================================
Files 30 30
Lines 2433 2463 +30
==========================================
+ Hits 1665 1694 +29
- Misses 599 602 +3
+ Partials 169 167 -2 ☔ View full report in Codecov by Harness. |
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.
Change type
Please select: 🆕 New feature or enhancement|🔧 Bug fix'|📃 Documentation update
Short description
Fixes
Full description
Checklist