fix: prevent nil embedded Reference panic on sibling operations when a $ref fails to build (#616) - #623
Open
rifkir23 wants to merge 1 commit into
Open
Conversation
…a $ref fails to build (pb33f#616)
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #623 +/- ##
==========================================
- Coverage 99.78% 99.75% -0.03%
==========================================
Files 283 283
Lines 34456 34458 +2
==========================================
- Hits 34382 34374 -8
- Misses 46 55 +9
- Partials 28 29 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
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.
Problem
When one operation in a path item fails to build (for example, an operation whose response schema is a dangling
$ref),BuildV3Modelstill returns a model along with the error. The sibling operations in that same path item are returned with a nil embedded*low.Reference, so callingIsReference()on them panics:A single bad
$refcan therefore take down anything that walks the model. This is hit in practice throughdaveshanley/vacuum(which walks the model withpb33f/doctor).Fixes #616
Reproduction
Two operations in one path item, only
gethas the dangling$ref:It needs two or more operations in the same path item; a single-operation path item does not reproduce it.
Root cause
Operationembeds*low.Reference(a pointer), and that embedded pointer is only initialized insideOperation.Build():In
PathItem.Build, operations are built viaTranslateSliceParallel. When one operation returns an error, the translate loop stops, so sibling operations that were constructed withlow.BuildModel(which intentionally skips embedded/anonymous fields) but never reachedBuild()keep a nil embedded*low.Reference.IsReference()has a value receiver, so invoking it through the nil embedded pointer dereferences nil and panics.Fix
Initialize the embedded reference at construction time, right after
low.BuildModel, for both standard and additional operations. The operation is then always safe to inspect, even if a sibling operation fails to build and this one is never built. This does not change the reported$referror, only the state of the model returned alongside it.Tests
Added
TestPathItem_Build_SiblingOperationSafeAfterRefError(low/v3): builds a path item with a dangling$refon one operation, asserts the build surfaces the error, and asserts the sibling operation is non-nil andIsReference()does not panic. Verified it FAILS with a nil pointer dereference without the fix and PASSES with it. Fulldatamodel/low/v3anddatamodel/high/v3suites pass; gofmt and go vet clean.