Description
When validating an optional query parameter with a schema default, if the client sends the parameter with an empty value (e.g.
?flag=), ValidateParameter decodes it as present but unparseable (found=true, decoded value is nil). It then injects the
schema default into the request URL using q.Add, which does not remove the existing empty value. The result is duplicate
query values for the same parameter name.
OpenAPI definition
openapi: 3.0.0
info:
title: repro
version: 1.0.0
paths:
/test:
get:
parameters:
- name: flag
in: query
required: false
schema:
type: boolean
default: false
responses:
'200':
description: ok
Reproduction
- Send:
GET /test?flag=
- Go parses this as:
url.Values{"flag": [""]}
- Call
ValidateParameter(...) (via ValidateRequest on a matching route)
Actual behavior
After validation, req.URL.Query()["flag"] is ["", "false"] (encoded as flag=&flag=false).
Validation passes (the in-memory value becomes the default false), but the request URL ends up with two values for a single-value
parameter.
Relevant code:
Expected behavior
When applying a default for a query parameter that is already present with an empty/unparseable value, the library should not
produce duplicate keys. For example:
- replace the existing value (
q.Set), or
- remove existing values before adding the default, or
- reject the empty value when
allowEmptyValue is false
At minimum: req.URL.Query()["flag"] should be ["false"], not ["", "false"].
Environment
- kin-openapi: v0.131.0 (also reproduced on latest master)
- Go: 1.22+
Test case
See PR: #1254
Description
When validating an optional query parameter with a schema default, if the client sends the parameter with an empty value (e.g.
?flag=),ValidateParameterdecodes it as present but unparseable (found=true, decoded value is nil). It then injects theschema default into the request URL using
q.Add, which does not remove the existing empty value. The result is duplicatequery values for the same parameter name.
OpenAPI definition
Reproduction
GET /test?flag=url.Values{"flag": [""]}ValidateParameter(...)(viaValidateRequeston a matching route)Actual behavior
After validation,
req.URL.Query()["flag"]is["", "false"](encoded asflag=&flag=false).Validation passes (the in-memory value becomes the default
false), but the request URL ends up with two values for a single-valueparameter.
Relevant code:
populateDefaultQueryParameters)parsePrimitivereturns nil forraw == ""):https://github.com/getkin/kin-openapi/blob/master/openapi3filter/req_resp_decoder.go
Expected behavior
When applying a default for a query parameter that is already present with an empty/unparseable value, the library should not
produce duplicate keys. For example:
q.Set), orallowEmptyValueis falseAt minimum:
req.URL.Query()["flag"]should be["false"], not["", "false"].Environment
Test case
See PR: #1254