diff --git a/go.mod b/go.mod index 87c3653..72d0b71 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/pb33f/libopenapi-validator -go 1.25.0 +go 1.25.7 require ( github.com/basgys/goxml2json v1.1.1-0.20231018121955-e66ee54ceaad @@ -8,10 +8,10 @@ require ( github.com/go-openapi/jsonpointer v0.23.1 github.com/goccy/go-yaml v1.19.2 github.com/pb33f/jsonpath v0.8.2 - github.com/pb33f/libopenapi v0.37.2 + github.com/pb33f/libopenapi v0.38.0 github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 github.com/stretchr/testify v1.11.1 - go.yaml.in/yaml/v4 v4.0.0-rc.4 + go.yaml.in/yaml/v4 v4.0.0-rc.5 golang.org/x/text v0.37.0 ) @@ -24,7 +24,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect golang.org/x/net v0.50.0 // indirect - golang.org/x/sync v0.20.0 // indirect + golang.org/x/sync v0.21.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index d8a0ec2..f76ea1b 100644 --- a/go.sum +++ b/go.sum @@ -30,6 +30,8 @@ github.com/pb33f/jsonpath v0.8.2 h1:Ou4C7zjYClBm97dfZjDCjdZGusJoynv/vrtiEKNfj2Y= github.com/pb33f/jsonpath v0.8.2/go.mod h1:zBV5LJW4OQOPatmQE2QdKpGQJvhDTlE5IEj6ASaRNTo= github.com/pb33f/libopenapi v0.37.2 h1:4Kb4w/h2BVKb099oYIZqeDxEBhUioWA+z6WJhBOk2r8= github.com/pb33f/libopenapi v0.37.2/go.mod h1:MsDdUlQ1CdrIDO5v26JfgBxQs7kcaOUEpMP3EqU6bI4= +github.com/pb33f/libopenapi v0.38.0 h1:OG+AMr2dMeB0BZdmm+j6iFy3Uxyl+W0HZpdD72zcyGs= +github.com/pb33f/libopenapi v0.38.0/go.mod h1:HrXjcGH/igq+/Af5l5/hmDD+yQRBRiTHgl0FmLdCZjg= github.com/pb33f/ordered-map/v2 v2.3.1 h1:5319HDO0aw4DA4gzi+zv4FXU9UlSs3xGZ40wcP1nBjY= github.com/pb33f/ordered-map/v2 v2.3.1/go.mod h1:qxFQgd0PkVUtOMCkTapqotNgzRhMPL7VvaHKbd1HnmQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -45,6 +47,8 @@ github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.yaml.in/yaml/v4 v4.0.0-rc.4 h1:UP4+v6fFrBIb1l934bDl//mmnoIZEDK0idg1+AIvX5U= go.yaml.in/yaml/v4 v4.0.0-rc.4/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= +go.yaml.in/yaml/v4 v4.0.0-rc.5 h1:JVliQq9EGOYaTgMi+k8BhUJyqcGk4ZqeuiN1Cirba9c= +go.yaml.in/yaml/v4 v4.0.0-rc.5/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= @@ -63,6 +67,8 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= +golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/schema_validation/validate_document.go b/schema_validation/validate_document.go index d539db4..e1ef930 100644 --- a/schema_validation/validate_document.go +++ b/schema_validation/validate_document.go @@ -236,7 +236,7 @@ func ValidateOpenAPIDocumentWithPrecompiled(doc libopenapi.Document, compiledSch var validationErrors []*liberrors.ValidationError // Check if both JSON representations are nil before proceeding - if info.SpecJSON == nil && info.SpecJSONBytes == nil { + if info.GetSpecJSON() == nil && info.GetSpecJSONBytes() == nil { validationErrors = append(validationErrors, &liberrors.ValidationError{ ValidationType: helpers.Schema, ValidationSubType: "document", @@ -279,13 +279,13 @@ func ValidateOpenAPIDocumentWithPrecompiled(doc libopenapi.Document, compiledSch // Build the normalized document value for validation. // Prefer SpecJSONBytes (single unmarshal) over SpecJSON (marshal+unmarshal round-trip). var normalized any - if info.SpecJSONBytes != nil && len(*info.SpecJSONBytes) > 0 { + if info.GetSpecJSONBytes() != nil && len(*info.GetSpecJSONBytes()) > 0 { var err error - normalized, err = jsonschema.UnmarshalJSON(bytes.NewReader(*info.SpecJSONBytes)) + normalized, err = jsonschema.UnmarshalJSON(bytes.NewReader(*info.GetSpecJSONBytes())) if err != nil { // Fall back to normalizeJSON if UnmarshalJSON fails - if info.SpecJSON != nil { - normalized, err = normalizeJSON(*info.SpecJSON) + if info.GetSpecJSON() != nil { + normalized, err = normalizeJSON(*info.GetSpecJSON()) if err != nil { return false, []*liberrors.ValidationError{buildDocumentDecodeError( fmt.Sprintf("The OpenAPI document cannot be converted to JSON: %s", err.Error()), @@ -299,9 +299,9 @@ func ValidateOpenAPIDocumentWithPrecompiled(doc libopenapi.Document, compiledSch )} } } - } else if info.SpecJSON != nil { + } else if info.GetSpecJSON() != nil { var err error - normalized, err = normalizeJSON(*info.SpecJSON) + normalized, err = normalizeJSON(*info.GetSpecJSON()) if err != nil { return false, []*liberrors.ValidationError{buildDocumentDecodeError( fmt.Sprintf("The OpenAPI document cannot be converted to JSON: %s", err.Error()), diff --git a/schema_validation/validate_document_test.go b/schema_validation/validate_document_test.go index 6f8e2f1..dc7a56a 100644 --- a/schema_validation/validate_document_test.go +++ b/schema_validation/validate_document_test.go @@ -210,8 +210,9 @@ paths: {}` }, } info := doc.GetSpecInfo() - info.SpecJSON = &badSpecJSON - info.SpecJSONBytes = nil + info.GetSpecJSON() + info.SpecJSON = &badSpecJSON //nolint:staticcheck + info.SpecJSONBytes = nil //nolint:staticcheck valid, errors := ValidateOpenAPIDocument(doc) @@ -240,8 +241,9 @@ paths: {}` } corrupt := []byte(`{not valid json!!!}`) info := doc.GetSpecInfo() - info.SpecJSON = &badSpecJSON - info.SpecJSONBytes = &corrupt + info.GetSpecJSON() + info.SpecJSON = &badSpecJSON //nolint:staticcheck + info.SpecJSONBytes = &corrupt //nolint:staticcheck valid, errors := ValidateOpenAPIDocument(doc) @@ -431,8 +433,9 @@ info: // Simulate the nil SpecJSON scenario by setting both to nil info := doc.GetSpecInfo() - info.SpecJSON = nil - info.SpecJSONBytes = nil + info.GetSpecJSON() + info.SpecJSON = nil //nolint:staticcheck + info.SpecJSONBytes = nil //nolint:staticcheck // validate! valid, errors := ValidateOpenAPIDocument(doc) @@ -460,6 +463,7 @@ func TestValidateDocument_WithPrecompiledSchema(t *testing.T) { doc, _ := libopenapi.NewDocument(petstore) info := doc.GetSpecInfo() + info.GetSpecJSON() // Pre-compile the schema options := config.NewValidationOptions() @@ -482,6 +486,7 @@ func TestValidateDocument_WithPrecompiledSchema_Invalid(t *testing.T) { doc, _ := libopenapi.NewDocument(petstore) info := doc.GetSpecInfo() + info.GetSpecJSON() // Pre-compile the schema options := config.NewValidationOptions() @@ -506,10 +511,11 @@ func TestValidateDocument_SpecJSONBytesPath(t *testing.T) { doc, _ := libopenapi.NewDocument(petstore) info := doc.GetSpecInfo() + info.GetSpecJSON() // Nil out SpecJSON but leave SpecJSONBytes intact — forces the SpecJSONBytes path - assert.NotNil(t, info.SpecJSONBytes, "SpecJSONBytes should be populated by libopenapi") - info.SpecJSON = nil + assert.NotNil(t, info.SpecJSONBytes, "SpecJSONBytes should be populated by libopenapi") //nolint:staticcheck + info.SpecJSON = nil //nolint:staticcheck valid, errs := ValidateOpenAPIDocument(doc) assert.True(t, valid) @@ -521,13 +527,14 @@ func TestValidateDocument_SpecJSONBytesCorrupt_NilSpecJSON(t *testing.T) { doc, _ := libopenapi.NewDocument(petstore) info := doc.GetSpecInfo() + info.GetSpecJSON() // Put corrupt bytes in SpecJSONBytes so UnmarshalJSON fails, // and nil out SpecJSON so the fallback normalizeJSON path is skipped. // This exercises the nil guard on SpecJSON inside the error branch. corrupt := []byte(`{not valid json!!!}`) - info.SpecJSONBytes = &corrupt - info.SpecJSON = nil + info.SpecJSONBytes = &corrupt //nolint:staticcheck + info.SpecJSON = nil //nolint:staticcheck // Validation should fail before JSON Schema validation instead of validating nil. valid, errs := ValidateOpenAPIDocument(doc) @@ -542,11 +549,12 @@ func TestValidateDocument_SpecJSONBytesCorrupt_FallbackToSpecJSON(t *testing.T) doc, _ := libopenapi.NewDocument(petstore) info := doc.GetSpecInfo() + info.GetSpecJSON() // Put corrupt bytes in SpecJSONBytes so UnmarshalJSON fails, // but leave SpecJSON intact so the fallback to normalizeJSON executes. corrupt := []byte(`{not valid json!!!}`) - info.SpecJSONBytes = &corrupt + info.SpecJSONBytes = &corrupt //nolint:staticcheck // Should still validate successfully via the SpecJSON fallback valid, errs := ValidateOpenAPIDocument(doc) @@ -559,10 +567,11 @@ func TestValidateDocument_SpecJSONBytesPath_Invalid(t *testing.T) { doc, _ := libopenapi.NewDocument(petstore) info := doc.GetSpecInfo() + info.GetSpecJSON() // Nil out SpecJSON but leave SpecJSONBytes intact - assert.NotNil(t, info.SpecJSONBytes, "SpecJSONBytes should be populated by libopenapi") - info.SpecJSON = nil + assert.NotNil(t, info.SpecJSONBytes, "SpecJSONBytes should be populated by libopenapi") //nolint:staticcheck + info.SpecJSON = nil //nolint:staticcheck valid, errs := ValidateOpenAPIDocument(doc) assert.False(t, valid)