Skip to content

Fix panic on missing or non-map query parameter object#278

Open
SebTardif wants to merge 3 commits into
pb33f:mainfrom
SebTardif:fix/query-param-panic
Open

Fix panic on missing or non-map query parameter object#278
SebTardif wants to merge 3 commits into
pb33f:mainfrom
SebTardif:fix/query-param-panic

Conversation

@SebTardif

Copy link
Copy Markdown

Problem

In parameters/query_parameters.go, the helpers.Object case uses a bare type assertion:

encodedObj[params[p].Name].(map[string]interface{})

This panics when:

  1. encodedObj is nil (e.g. content-wrapped parameter with a non-JSON media type skips map initialization)
  2. The key params[p].Name is absent from encodedObj (map lookup returns nil, bare assertion on nil panics)
  3. The value is present but is not a map[string]interface{}

Fix

Replace the bare type assertion with a three-step comma-ok pattern:

if encodedObj == nil {
    break skipValues
}
objVal, objExists := encodedObj[params[p].Name]
if !objExists || objVal == nil {
    break skipValues
}
objMap, mapOk := objVal.(map[string]interface{})
if !mapOk {
    break skipValues
}

This follows the existing control flow: when the value cannot be decoded, we break skipValues (the same pattern used for JSON unmarshal failures a few lines above).

Test

Added TestQueryParamObjectMissingKey_NoPanic which declares an object query parameter with a text/plain content wrapper. This forces the contentWrapped path without JSON decoding, leaving encodedObj nil. Before the fix, this test panics. After the fix, it completes without error.

Replace bare type assertion with comma-ok pattern to prevent panic
when query parameter object key is absent or value is not a map.
@codecov

codecov Bot commented May 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.77778% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.53%. Comparing base (54cf7b7) to head (069d2e1).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
parameters/query_parameters.go 46.66% 6 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #278      +/-   ##
==========================================
- Coverage   97.63%   97.53%   -0.11%     
==========================================
  Files          64       64              
  Lines        6991     7026      +35     
==========================================
+ Hits         6826     6853      +27     
- Misses        132      138       +6     
- Partials       33       35       +2     
Flag Coverage Δ
unittests 97.53% <77.77%> (-0.11%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@daveshanley

Copy link
Copy Markdown
Member

two lines missing coverage... you can do it :)

Comment thread parameters/query_parameters.go
The nil/type guards prevented the panic but also silently accepted
requests where a content-wrapped object parameter could not be decoded
into a map. Now each guard emits a QueryParameterCannotBeDecoded
validation error before breaking, so the request correctly fails
validation instead of passing silently.

Add QueryParameterCannotBeDecoded error constructor (modeled after
HeaderParameterCannotBeDecoded) and update the test to assert on the
returned error. Add a positive test for valid JSON object parameters.

Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
@SebTardif

Copy link
Copy Markdown
Author

@daveshanley

two lines missing coverage... you can do it :)

Fixed in d002a64. The guards now emit a QueryParameterCannotBeDecoded validation error (modeled after HeaderParameterCannotBeDecoded) instead of silently breaking. Updated the test to assert on the returned error and added a positive test for valid JSON object parameters.

@daveshanley

Copy link
Copy Markdown
Member

Coverage is a big drop-off; need to bring it up! The libs are something I am anal about coverage on.

… paths

Add unit test for QueryParameterCannotBeDecoded error constructor in
errors/ package (21 lines, 0% -> 100% per-package coverage).

Add integration tests for query parameter object validation:
- JSON content-wrapped with invalid property type (schema error path)
- Form-encoded valid and invalid objects (non-content-wrapped path)
- XML content type (second encodedObj==nil guard path)

These bring patch coverage from 19% to ~78% and restore the errors/
package from 98.0% to 98.9%.

Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
@SebTardif

Copy link
Copy Markdown
Author

@daveshanley Coverage improved in 069d2e1:

  • errors/parameter_errors.go: QueryParameterCannotBeDecoded now has a direct unit test in the errors/ package (0% to 100% per-package coverage, 98.0% to 98.9% overall).
  • parameters/query_parameters_test.go: Added 5 integration tests covering JSON content-wrapped (valid + invalid schema), form-encoded (valid + invalid), and XML content type paths through the object parameter validation.

The remaining uncovered lines are the bodies of guards 2 and 3 (!objExists || objVal == nil and !mapOk). These are defensive checks: all current encoding helpers (ConstructParamMapFromFormEncodingArrayWithSchema, ConstructParamMapFromDeepObjectEncoding, etc.) always produce a map[string]interface{} value for the parameter key, so the guard bodies are unreachable through the public API. They protect against future changes to the helper functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants