Skip to content

Commit 7aa3c9e

Browse files
authored
reproduce + fix #444: ValidateRequest for application/x-yaml (#445)
1 parent e9b36da commit 7aa3c9e

File tree

2 files changed

+73
-6
lines changed

2 files changed

+73
-6
lines changed

openapi3/schema.go

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -800,13 +800,22 @@ func (schema *Schema) visitJSON(settings *schemaValidationSettings, value interf
800800
return schema.visitJSONArray(settings, value)
801801
case map[string]interface{}:
802802
return schema.visitJSONObject(settings, value)
803-
default:
804-
return &SchemaError{
805-
Value: value,
806-
Schema: schema,
807-
SchemaField: "type",
808-
Reason: fmt.Sprintf("unhandled value of type %T", value),
803+
case map[interface{}]interface{}: // for YAML cf. issue #444
804+
values := make(map[string]interface{}, len(value))
805+
for key, v := range value {
806+
if k, ok := key.(string); ok {
807+
values[k] = v
808+
}
809809
}
810+
if len(value) == len(values) {
811+
return schema.visitJSONObject(settings, values)
812+
}
813+
}
814+
return &SchemaError{
815+
Value: value,
816+
Schema: schema,
817+
SchemaField: "type",
818+
Reason: fmt.Sprintf("unhandled value of type %T", value),
810819
}
811820
}
812821

routers/legacy/issue444_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package legacy_test
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"net/http/httptest"
7+
"testing"
8+
9+
"github.com/getkin/kin-openapi/openapi3"
10+
"github.com/getkin/kin-openapi/openapi3filter"
11+
legacyrouter "github.com/getkin/kin-openapi/routers/legacy"
12+
"github.com/stretchr/testify/require"
13+
)
14+
15+
func TestIssue444(t *testing.T) {
16+
loader := openapi3.NewLoader()
17+
oas, err := loader.LoadFromData([]byte(`
18+
openapi: '3.0.0'
19+
info:
20+
title: API
21+
version: 1.0.0
22+
paths:
23+
'/path':
24+
post:
25+
requestBody:
26+
required: true
27+
content:
28+
application/x-yaml:
29+
schema:
30+
type: object
31+
responses:
32+
'200':
33+
description: x
34+
content:
35+
application/json:
36+
schema:
37+
type: string
38+
`))
39+
require.NoError(t, err)
40+
router, err := legacyrouter.NewRouter(oas)
41+
require.NoError(t, err)
42+
43+
r := httptest.NewRequest("POST", "/path", bytes.NewReader([]byte(`
44+
foo: bar
45+
`)))
46+
r.Header.Set("Content-Type", "application/x-yaml")
47+
48+
openapi3.SchemaErrorDetailsDisabled = true
49+
route, pathParams, err := router.FindRoute(r)
50+
require.NoError(t, err)
51+
reqValidationInput := &openapi3filter.RequestValidationInput{
52+
Request: r,
53+
PathParams: pathParams,
54+
Route: route,
55+
}
56+
err = openapi3filter.ValidateRequest(context.Background(), reqValidationInput)
57+
require.NoError(t, err)
58+
}

0 commit comments

Comments
 (0)