Skip to content

Commit 330c142

Browse files
authored
Actually #624, thanks to @orensolo (#634)
1 parent e887ba8 commit 330c142

File tree

4 files changed

+37
-41
lines changed

4 files changed

+37
-41
lines changed

openapi3filter/issue624_test.go

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,22 @@ paths:
4848

4949
router, err := gorillamux.NewRouter(doc)
5050
require.NoError(t, err)
51-
httpReq, err := http.NewRequest(http.MethodGet, `/items?test=test1`, nil)
52-
require.NoError(t, err)
5351

54-
route, pathParams, err := router.FindRoute(httpReq)
55-
require.NoError(t, err)
52+
for _, testcase := range []string{`test1`, `test[1`} {
53+
t.Run(testcase, func(t *testing.T) {
54+
httpReq, err := http.NewRequest(http.MethodGet, `/items?test=`+testcase, nil)
55+
require.NoError(t, err)
5656

57-
requestValidationInput := &RequestValidationInput{
58-
Request: httpReq,
59-
PathParams: pathParams,
60-
Route: route,
57+
route, pathParams, err := router.FindRoute(httpReq)
58+
require.NoError(t, err)
59+
60+
requestValidationInput := &RequestValidationInput{
61+
Request: httpReq,
62+
PathParams: pathParams,
63+
Route: route,
64+
}
65+
err = ValidateRequest(ctx, requestValidationInput)
66+
require.NoError(t, err)
67+
})
6168
}
62-
err = ValidateRequest(ctx, requestValidationInput)
63-
require.NoError(t, err)
6469
}

openapi3filter/req_resp_decoder.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,11 @@ func invalidSerializationMethodErr(sm *openapi3.SerializationMethod) error {
110110
// Decodes a parameter defined via the content property as an object. It uses
111111
// the user specified decoder, or our build-in decoder for application/json
112112
func decodeContentParameter(param *openapi3.Parameter, input *RequestValidationInput) (
113-
value interface{}, schema *openapi3.Schema, found bool, err error) {
114-
113+
value interface{},
114+
schema *openapi3.Schema,
115+
found bool,
116+
err error,
117+
) {
115118
var paramValues []string
116119
switch param.In {
117120
case openapi3.ParameterInPath:
@@ -186,28 +189,25 @@ func defaultContentParameterDecoder(param *openapi3.Parameter, values []string)
186189
}
187190
outSchema = mt.Schema.Value
188191

189-
unmarshal := func(encoded string) (decoded interface{}, err error) {
192+
unmarshal := func(encoded string, paramSchema *openapi3.SchemaRef) (decoded interface{}, err error) {
190193
if err = json.Unmarshal([]byte(encoded), &decoded); err != nil {
191-
const specialJSONChars = `[]{}":,`
192-
if !strings.ContainsAny(encoded, specialJSONChars) {
193-
// A string in a query parameter is not serialized with (double) quotes
194-
// as JSON would expect, so let's fallback to that.
194+
if paramSchema != nil && paramSchema.Value.Type != "object" {
195195
decoded, err = encoded, nil
196196
}
197197
}
198198
return
199199
}
200200

201201
if len(values) == 1 {
202-
if outValue, err = unmarshal(values[0]); err != nil {
202+
if outValue, err = unmarshal(values[0], mt.Schema); err != nil {
203203
err = fmt.Errorf("error unmarshaling parameter %q", param.Name)
204204
return
205205
}
206206
} else {
207207
outArray := make([]interface{}, 0, len(values))
208208
for _, v := range values {
209209
var item interface{}
210-
if item, err = unmarshal(v); err != nil {
210+
if item, err = unmarshal(v, outSchema.Items); err != nil {
211211
err = fmt.Errorf("error unmarshaling parameter %q", param.Name)
212212
return
213213
}

openapi3filter/validate_request.go

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,8 @@ var ErrInvalidEmptyValue = errors.New("empty value is not allowed")
2828
//
2929
// Note: One can tune the behavior of uniqueItems: true verification
3030
// by registering a custom function with openapi3.RegisterArrayUniqueItemsChecker
31-
func ValidateRequest(ctx context.Context, input *RequestValidationInput) error {
32-
var (
33-
err error
34-
me openapi3.MultiError
35-
)
31+
func ValidateRequest(ctx context.Context, input *RequestValidationInput) (err error) {
32+
var me openapi3.MultiError
3633

3734
options := input.Options
3835
if options == nil {
@@ -52,9 +49,8 @@ func ValidateRequest(ctx context.Context, input *RequestValidationInput) error {
5249
}
5350
if security != nil {
5451
if err = ValidateSecurityRequirements(ctx, input, *security); err != nil && !options.MultiError {
55-
return err
52+
return
5653
}
57-
5854
if err != nil {
5955
me = append(me, err)
6056
}
@@ -70,9 +66,8 @@ func ValidateRequest(ctx context.Context, input *RequestValidationInput) error {
7066
}
7167

7268
if err = ValidateParameter(ctx, input, parameter); err != nil && !options.MultiError {
73-
return err
69+
return
7470
}
75-
7671
if err != nil {
7772
me = append(me, err)
7873
}
@@ -81,9 +76,8 @@ func ValidateRequest(ctx context.Context, input *RequestValidationInput) error {
8176
// For each parameter of the Operation
8277
for _, parameter := range operationParameters {
8378
if err = ValidateParameter(ctx, input, parameter.Value); err != nil && !options.MultiError {
84-
return err
79+
return
8580
}
86-
8781
if err != nil {
8882
me = append(me, err)
8983
}
@@ -93,9 +87,8 @@ func ValidateRequest(ctx context.Context, input *RequestValidationInput) error {
9387
requestBody := operation.RequestBody
9488
if requestBody != nil && !options.ExcludeRequestBody {
9589
if err = ValidateRequestBody(ctx, input, requestBody.Value); err != nil && !options.MultiError {
96-
return err
90+
return
9791
}
98-
9992
if err != nil {
10093
me = append(me, err)
10194
}
@@ -104,8 +97,7 @@ func ValidateRequest(ctx context.Context, input *RequestValidationInput) error {
10497
if len(me) > 0 {
10598
return me
10699
}
107-
108-
return nil
100+
return
109101
}
110102

111103
// ValidateParameter validates a parameter's value by JSON schema.

openapi3filter/validation_test.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ func TestFilter(t *testing.T) {
198198
}
199199
err = ValidateResponse(context.Background(), responseValidationInput)
200200
require.NoError(t, err)
201-
return err
201+
return nil
202202
}
203203
expect := func(req ExampleRequest, resp ExampleResponse) error {
204204
return expectWithDecoder(req, resp, nil)
@@ -207,13 +207,12 @@ func TestFilter(t *testing.T) {
207207
resp := ExampleResponse{
208208
Status: 200,
209209
}
210-
// Test paths
211210

211+
// Test paths
212212
req := ExampleRequest{
213213
Method: "POST",
214214
URL: "http://example.com/api/prefix/v/suffix",
215215
}
216-
217216
err = expect(req, resp)
218217
require.NoError(t, err)
219218

@@ -328,15 +327,15 @@ func TestFilter(t *testing.T) {
328327
// enough.
329328
req = ExampleRequest{
330329
Method: "POST",
331-
URL: "http://example.com/api/prefix/v/suffix?contentArg={\"name\":\"bob\", \"id\":\"a\"}",
330+
URL: `http://example.com/api/prefix/v/suffix?contentArg={"name":"bob", "id":"a"}`,
332331
}
333332
err = expect(req, resp)
334333
require.NoError(t, err)
335334

336335
// Now it should fail due the ID being too long
337336
req = ExampleRequest{
338337
Method: "POST",
339-
URL: "http://example.com/api/prefix/v/suffix?contentArg={\"name\":\"bob\", \"id\":\"EXCEEDS_MAX_LENGTH\"}",
338+
URL: `http://example.com/api/prefix/v/suffix?contentArg={"name":"bob", "id":"EXCEEDS_MAX_LENGTH"}`,
340339
}
341340
err = expect(req, resp)
342341
require.IsType(t, &RequestError{}, err)
@@ -351,15 +350,15 @@ func TestFilter(t *testing.T) {
351350

352351
req = ExampleRequest{
353352
Method: "POST",
354-
URL: "http://example.com/api/prefix/v/suffix?contentArg2={\"name\":\"bob\", \"id\":\"a\"}",
353+
URL: `http://example.com/api/prefix/v/suffix?contentArg2={"name":"bob", "id":"a"}`,
355354
}
356355
err = expectWithDecoder(req, resp, customDecoder)
357356
require.NoError(t, err)
358357

359358
// Now it should fail due the ID being too long
360359
req = ExampleRequest{
361360
Method: "POST",
362-
URL: "http://example.com/api/prefix/v/suffix?contentArg2={\"name\":\"bob\", \"id\":\"EXCEEDS_MAX_LENGTH\"}",
361+
URL: `http://example.com/api/prefix/v/suffix?contentArg2={"name":"bob", "id":"EXCEEDS_MAX_LENGTH"}`,
363362
}
364363
err = expectWithDecoder(req, resp, customDecoder)
365364
require.IsType(t, &RequestError{}, err)

0 commit comments

Comments
 (0)