BindQueryParameter cannot distinguish delimiter commas from literal commas in form/explode=false values

Problem

When using style=form, explode=false for query parameters containing array values where an element itself contains a comma, BindQueryParameter cannot correctly deserialize the value.

Per the OpenAPI 3.0 spec, the serialized form should be:

value: ["a", "b", "c,d"]
query: search_term=a,b,c%2Cd

Delimiter commas are literal, and commas within values are percent-encoded as %2C.

What happens

BindQueryParameter receives url.Values, which Go's HTTP stack has already URL-decoded. By the time the runtime sees the value, %2C has been decoded back to ,, making it indistinguishable from the delimiter commas:

// Go's net/http parses "search_term=a,b,c%2Cd" into:
// url.Values{"search_term": ["a,b,c,d"]}
//
// BindQueryParameter then does:
// strings.Split("a,b,c,d", ",") → ["a", "b", "c", "d"]  // 4 elements, expected 3

Client side is fixed

The client side of this was fixed in oapi-codegen/oapi-codegen#2184StyleParamWithLocation correctly produces search_term=a,b,c%2Cd (individual values are url.QueryEscape'd before joining with literal comma delimiters). The generated client template was updated to preserve these raw fragments instead of round-tripping through url.ParseQuery/url.Values.Encode().

Suggested fix

To fix the server side, BindQueryParameter (or a new variant) would need access to the raw, undecoded query string (r.URL.RawQuery) rather than url.Values. It could then:

  1. Extract the raw parameter value (splitting on & and = without decoding)
  2. Split on literal , to get the individual encoded parts
  3. URL-decode each part individually

This would correctly yield ["a", "b", "c,d"].

This would also require changes to the server templates in oapi-codegen to pass the raw query string instead of (or in addition to) url.Values.

Related