Skip to content

Commit

Permalink
fix: issue unmarshalling when discriminator field is set in openapi2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
reversearrow committed Sep 17, 2024
1 parent c606b55 commit e17e91d
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 4 deletions.
97 changes: 97 additions & 0 deletions openapi2/issues1010_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package openapi2

import (
"encoding/json"
"testing"

"github.com/stretchr/testify/require"
)

func TestIssue1010(t *testing.T) {
v2 := []byte(`
{
"basePath": "/v2",
"host": "test.example.com",
"info": {
"title": "MyAPI",
"version": "0.1",
"x-info": "info extension"
},
"paths": {
"/foo": {
"get": {
"operationId": "getFoo",
"responses": {
"200": {
"description": "returns all information",
"schema": {
"$ref": "#/definitions/Pet"
}
},
"default": {
"description": "OK"
}
},
"summary": "get foo"
}
}
},
"schemes": [
"http"
],
"swagger": "2.0",
"definitions": {
"Pet": {
"type": "object",
"required": ["petType"],
"properties": {
"petType": {
"type": "string"
},
"name": {
"type": "string"
},
"age": {
"type": "integer"
}
},
"discriminator": "petType"
},
"Dog": {
"allOf": [
{
"$ref": "#/definitions/Pet"
},
{
"type": "object",
"properties": {
"breed": {
"type": "string"
}
}
}
]
},
"Cat": {
"allOf": [
{
"$ref": "#/definitions/Pet"
},
{
"type": "object",
"properties": {
"color": {
"type": "string"
}
}
}
]
}
}
}
`)

var doc2 T
err := json.Unmarshal(v2, &doc2)
require.NoError(t, err)
}
13 changes: 12 additions & 1 deletion openapi3/discriminator_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package openapi3

import (
"encoding/json"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -52,5 +53,15 @@ func TestParsingDiscriminator(t *testing.T) {
err = doc.Validate(loader.Context)
require.NoError(t, err)

require.Len(t, doc.Components.Schemas["MyResponseType"].Value.Discriminator.Mapping, 2)
discriminatorMap, ok := doc.Components.Schemas["MyResponseType"].Value.Discriminator.(map[string]interface{})
require.True(t, ok)

discriminatorBytes, err := json.Marshal(discriminatorMap)
require.NoError(t, err)

var discriminator *Discriminator
err = json.Unmarshal(discriminatorBytes, &discriminator)
require.NoError(t, err)

require.Len(t, discriminator.Mapping, 2)
}
33 changes: 30 additions & 3 deletions openapi3/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ type Schema struct {
MinProps uint64 `json:"minProperties,omitempty" yaml:"minProperties,omitempty"`
MaxProps *uint64 `json:"maxProperties,omitempty" yaml:"maxProperties,omitempty"`
AdditionalProperties AdditionalProperties `json:"additionalProperties,omitempty" yaml:"additionalProperties,omitempty"`
Discriminator *Discriminator `json:"discriminator,omitempty" yaml:"discriminator,omitempty"`
Discriminator interface{} `json:"discriminator,omitempty" yaml:"discriminator,omitempty"`
}

type Types []string
Expand Down Expand Up @@ -1298,7 +1298,33 @@ func (schema *Schema) visitXOFOperations(settings *schemaValidationSettings, val
if v := schema.OneOf; len(v) > 0 {
var discriminatorRef string
if schema.Discriminator != nil {
pn := schema.Discriminator.PropertyName
var discriminator *Discriminator
if descriminatorValuemap, okcheck := schema.Discriminator.(map[string]any); okcheck {
marshaledDiscriminator, err := json.Marshal(descriminatorValuemap)
if err != nil {
return &SchemaError{
Schema: schema,
SchemaField: "discriminator",
Reason: fmt.Sprintf("unable to marshal the discriminator field in schema: %v", err),
}, false
}

if err := json.Unmarshal(marshaledDiscriminator, &discriminator); err != nil {
return &SchemaError{
Schema: schema,
SchemaField: "discriminator",
Reason: fmt.Sprintf("unable to unmarshall the discriminator field in schema: %v", err),
}, false
}
} else {
return &SchemaError{
Schema: schema,
SchemaField: "discriminator",
Reason: fmt.Sprintf("discriminator is expected to be an object, but received an unknown type"),
}, false
}

pn := discriminator.PropertyName
if valuemap, okcheck := value.(map[string]any); okcheck {
discriminatorVal, okcheck := valuemap[pn]
if !okcheck {
Expand All @@ -1319,7 +1345,7 @@ func (schema *Schema) visitXOFOperations(settings *schemaValidationSettings, val
}, false
}

if discriminatorRef, okcheck = schema.Discriminator.Mapping[discriminatorValString]; len(schema.Discriminator.Mapping) > 0 && !okcheck {
if discriminatorRef, okcheck = discriminator.Mapping[discriminatorValString]; len(discriminator.Mapping) > 0 && !okcheck {
return &SchemaError{
Value: discriminatorVal,
Schema: schema,
Expand All @@ -1328,6 +1354,7 @@ func (schema *Schema) visitXOFOperations(settings *schemaValidationSettings, val
}, false
}
}

}

var (
Expand Down

0 comments on commit e17e91d

Please sign in to comment.