Skip to content

Commit 0fb1f0e

Browse files
authored
openapi3filter: skip schema checks for empty allowEmptyValue strings (#1228)
1 parent a872c57 commit 0fb1f0e

2 files changed

Lines changed: 112 additions & 0 deletions

File tree

openapi3filter/issue1134_test.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package openapi3filter_test
2+
3+
import (
4+
"net/http"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
9+
"github.com/getkin/kin-openapi/openapi3"
10+
"github.com/getkin/kin-openapi/openapi3filter"
11+
"github.com/getkin/kin-openapi/routers/gorillamux"
12+
)
13+
14+
// Empty string query params used to become nil in parsePrimitive, which skipped
15+
// schema checks. After #1096 they stay "", so format:date was applied even when
16+
// allowEmptyValue is true. See #1134.
17+
func TestIssue1134(t *testing.T) {
18+
spec := `
19+
openapi: 3.0.3
20+
info:
21+
title: issue 1134
22+
version: 0.0.1
23+
paths:
24+
/people:
25+
get:
26+
parameters:
27+
- name: dateOfBirth
28+
in: query
29+
required: false
30+
allowEmptyValue: true
31+
schema:
32+
type: string
33+
format: date
34+
- name: updatedAt
35+
in: query
36+
required: false
37+
allowEmptyValue: true
38+
schema:
39+
type: string
40+
format: date-time
41+
- name: strictDate
42+
in: query
43+
required: false
44+
schema:
45+
type: string
46+
format: date
47+
responses:
48+
'200':
49+
description: ok
50+
`[1:]
51+
52+
loader := openapi3.NewLoader()
53+
doc, err := loader.LoadFromData([]byte(spec))
54+
require.NoError(t, err)
55+
require.NoError(t, doc.Validate(loader.Context))
56+
57+
router, err := gorillamux.NewRouter(doc)
58+
require.NoError(t, err)
59+
60+
for _, tc := range []struct {
61+
name string
62+
url string
63+
shouldFail bool
64+
}{
65+
{
66+
name: "empty date with allowEmptyValue",
67+
url: "/people?dateOfBirth=",
68+
},
69+
{
70+
name: "empty date-time with allowEmptyValue",
71+
url: "/people?updatedAt=",
72+
},
73+
{
74+
name: "valid date still accepted",
75+
url: "/people?dateOfBirth=1970-01-01",
76+
},
77+
{
78+
name: "invalid non-empty date still rejected",
79+
url: "/people?dateOfBirth=not-a-date",
80+
shouldFail: true,
81+
},
82+
{
83+
name: "empty date without allowEmptyValue still rejected",
84+
url: "/people?strictDate=",
85+
shouldFail: true,
86+
},
87+
} {
88+
t.Run(tc.name, func(t *testing.T) {
89+
req, err := http.NewRequest(http.MethodGet, tc.url, nil)
90+
require.NoError(t, err)
91+
92+
route, pathParams, err := router.FindRoute(req)
93+
require.NoError(t, err)
94+
95+
err = openapi3filter.ValidateRequest(loader.Context, &openapi3filter.RequestValidationInput{
96+
Request: req,
97+
PathParams: pathParams,
98+
Route: route,
99+
})
100+
if tc.shouldFail {
101+
require.Error(t, err)
102+
} else {
103+
require.NoError(t, err)
104+
}
105+
})
106+
}
107+
}

openapi3filter/validate_request.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,11 @@ func ValidateParameter(ctx context.Context, input *RequestValidationInput, param
227227
}
228228
return nil
229229
}
230+
// #1096 keeps empty strings as ""; with allowEmptyValue skip schema checks
231+
// (format, pattern, ...) like we used to when the value was nil.
232+
if s, ok := value.(string); ok && s == "" && parameter.AllowEmptyValue {
233+
return nil
234+
}
230235
if schema == nil {
231236
// A parameter's schema is not defined so skip validation of a parameter's value.
232237
return nil

0 commit comments

Comments
 (0)