OpenAPITools / OpenAPITools/openapi-generator
[BUG][GO Server] Optional or invalid boolean query params are not properly checked.
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
Bug Report Checklist
- [x ] Have you provided a full/minimal spec to reproduce the issue?
- [ x] Have you validated the input using an OpenAPI validator (example)?
- [ x] Have you tested with the latest master to confirm the issue still exists?
- [x ] Have you searched for related issues/PRs?
- [ x] What's the actual output vs expected output?
- [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description
When the payload have one or more optional query param booleans and is not set or set incorrectly, the server returns 500 response with no body and it swallows the error. There's nothing in the logs either to indicate what went wrong.
The root cause is that the parseBoolParameter function does not check if the value is valid and the router function does not call the errorHandler.
openapi-generator version
5.3.0
OpenAPI declaration file content or url
openapi: 3.0.2
info:
description: example
title: test
version: 0.0.1
paths:
/reports:
get:
description: sampleBug
operationId: sampleBug
parameters:
- description: none
explode: true
in: query
name: fromStart
required: false
schema:
default: false
type: boolean
style: form
responses:
"202":
content:
application/json:
schema:
type: string
description: OK
"400":
content:
application/problem+json:
schema:
type: string
description: Error
"500":
content:
application/problem+json:
schema:
type: string
description: Error
summary: Update
Generation Details
Use the openapi-generator-cli bash script
openapi-generator-cli generate -i spec.yaml -g go-server --enable-post-process-file -o src/ -p featureCORS=true,packageName=test,packageVersion=0.0.1
api_default.go
...
// SampleBug - sampleBug
func (c *DefaultApiController) SampleBug(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
query := r.URL.Query()
fromStartParam, err := parseBoolParameter(query.Get("fromStart"))
if err != nil {
w.WriteHeader(500)
return
}
result, err := c.service.SampleBug(r.Context(), fromStartParam)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, w)
}
...
router.go
...
// parseBoolParameter parses a string parameter to a bool
func parseBoolParameter(param string) (bool, error) {
val, err := strconv.ParseBool(param)
if err != nil {
return false, err
}
return bool(val), nil
}
...
Steps to reproduce
Start the server and then make a request
# Example without optional parameter. Expected to use the default
curl localhost:8080/api/v1/reports
# Example with invalid parameter (should return a 4XX)
curl localhost:8080/api/v1/reports?fromStart=Yes
Related issues/PRs
N/A
Suggest a fix
For optional boolean with default, it requires a new function
routers.go
...
// parseOptionalBoolParameter parses an optional string parameter to a bool
func parseOptionalBoolParameter(param string, defaultVaule bool) (bool, error) {
if IsZeroValue(param) {
return defaultVaule, nil
}
val, err := strconv.ParseBool(param)
if err != nil {
return false, err
}
return val, nil
}
...
api_default.go
...
// SampleBug - sampleBug
func (c *DefaultApiController) SampleBug(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
query := r.URL.Query()
fromStartParam, err := parseOptionalBoolParameter(query.Get("fromStart"), false)
if err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.SampleBug(r.Context(), fromStartParam)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, w)
}
...
For required boolean, it requires to update parseBoolParameter
routers.go
...
// parseBoolParameter parses an required string parameter to a bool
func parseBoolParameter(param string) (bool, error) {
if IsZeroValue(param) {
return false, errors.New(errMsgRequiredMissing)
}
val, err := strconv.ParseBool(param)
if err != nil {
return false, err
}
return val, nil
}
...
api_default.go
...
// SampleBug - sampleBug
func (c *DefaultApiController) SampleBug(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
query := r.URL.Query()
fromStartParam, err := parseBoolParameter(query.Get("fromStart"))
if err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.SampleBug(r.Context(), fromStartParam)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, w)
}
...
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the generated api_default.go and router.go/routers.go examples, then reproduce the behavior using the provided openapi-generator-cli command and curl requests. The work is done when omitted optional booleans use their defaults, invalid values reach errorHandler and return a 4XX response, and required missing values are reported rather than producing an empty 500 response.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 50/100