Skip to content

Commit 6a04fdf

Browse files
authored
openapi3: Allow usage of empty string (#1096)
1 parent 8933711 commit 6a04fdf

File tree

3 files changed

+39
-6
lines changed

3 files changed

+39
-6
lines changed

openapi3filter/req_resp_decoder.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,12 @@ func (d *urlValuesDecoder) parseArray(raw []string, sm *openapi3.SerializationMe
565565
}
566566
value = append(value, item)
567567
}
568+
// If the array has only one element and that element is an empty string, it means no value exists, so return nil.
569+
if len(value) == 1 {
570+
if str, ok := value[0].(string); ok && str == "" {
571+
return nil, nil
572+
}
573+
}
568574
return value, nil
569575
}
570576

@@ -1116,13 +1122,13 @@ func parseArray(raw []string, schemaRef *openapi3.SchemaRef) ([]any, error) {
11161122
}
11171123

11181124
// parsePrimitive returns a value that is created by parsing a source string to a primitive type
1119-
// that is specified by a schema. The function returns nil when the source string is empty.
1125+
// that is specified by a schema. The function returns nil when the source string is empty and the type is not "string".
11201126
// The function panics when a schema has a non-primitive type.
11211127
func parsePrimitive(raw string, schema *openapi3.SchemaRef) (v any, err error) {
1122-
if raw == "" {
1123-
return nil, nil
1124-
}
11251128
for _, typ := range schema.Value.Type.Slice() {
1129+
if raw == "" && typ != "string" {
1130+
return nil, nil
1131+
}
11261132
if v, err = parsePrimitiveCase(raw, schema, typ); err == nil {
11271133
return
11281134
}

openapi3filter/req_resp_decoder_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,13 +671,27 @@ func TestDecodeParameter(t *testing.T) {
671671
want: "foo",
672672
found: true,
673673
},
674+
{
675+
name: "string empty",
676+
param: &openapi3.Parameter{Name: "param", In: "query", Schema: stringSchema},
677+
query: "param=",
678+
want: "",
679+
found: true,
680+
},
674681
{
675682
name: "integer",
676683
param: &openapi3.Parameter{Name: "param", In: "query", Schema: integerSchema},
677684
query: "param=1",
678685
want: int64(1),
679686
found: true,
680687
},
688+
{
689+
name: "integer empty",
690+
param: &openapi3.Parameter{Name: "param", In: "query", Schema: integerSchema},
691+
query: "param=",
692+
want: nil,
693+
found: true,
694+
},
681695
{
682696
name: "integer invalid",
683697
param: &openapi3.Parameter{Name: "param", In: "query", Schema: integerSchema},
@@ -692,6 +706,13 @@ func TestDecodeParameter(t *testing.T) {
692706
want: 1.1,
693707
found: true,
694708
},
709+
{
710+
name: "number empty",
711+
param: &openapi3.Parameter{Name: "param", In: "query", Schema: numberSchema},
712+
query: "param=",
713+
want: nil,
714+
found: true,
715+
},
695716
{
696717
name: "number invalid",
697718
param: &openapi3.Parameter{Name: "param", In: "query", Schema: numberSchema},
@@ -706,6 +727,13 @@ func TestDecodeParameter(t *testing.T) {
706727
want: true,
707728
found: true,
708729
},
730+
{
731+
name: "boolean empty",
732+
param: &openapi3.Parameter{Name: "param", In: "query", Schema: booleanSchema},
733+
query: "param=",
734+
want: nil,
735+
found: true,
736+
},
709737
{
710738
name: "boolean invalid",
711739
param: &openapi3.Parameter{Name: "param", In: "query", Schema: booleanSchema},

openapi3filter/validate_response_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ func Test_validateResponseHeader(t *testing.T) {
4242
},
4343
isHeaderPresent: true,
4444
headerVals: []string{""},
45-
wantErr: true,
46-
wantErrMsg: `response header "X-Blab" doesn't match schema: Value is not nullable`,
45+
wantErr: false,
4746
},
4847
{
4948
name: "test optional string header with single string value",

0 commit comments

Comments
 (0)