Skip to content

[bugfix] correctly differentiate between nil / present-but-empty slices#4498

Open
NyaaaWhatsUpDoc wants to merge 2 commits intogin-gonic:masterfrom
NyaaaWhatsUpDoc:bugfix/form-array-binding-regression
Open

[bugfix] correctly differentiate between nil / present-but-empty slices#4498
NyaaaWhatsUpDoc wants to merge 2 commits intogin-gonic:masterfrom
NyaaaWhatsUpDoc:bugfix/form-array-binding-regression

Conversation

@NyaaaWhatsUpDoc
Copy link

This fixes the regression introduced in v1.11.0 which stopped differentiating between nil and zero length (but not nil) slices when binding form values.

Pull Request Checklist

Please ensure your pull request meets the following requirements:

  • Open your pull request against the master branch.
  • All tests pass in available continuous integration systems (e.g., GitHub Actions).
  • Tests are added or modified as needed to cover code changes.
  • If the pull request introduces a new feature, the feature is documented in the docs/doc.md.

Thank you for contributing!

if cfTag == "" || cfTag == "multi" {
vs = strings.Split(opt.defaultValue, ",")
} else {
vs = []string{opt.defaultValue}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this isn't part of the fix (nor is it in the array part below), but it just means vs only needs to get written to once instead of twice in the case of cfTag == "" | cfTag == "multi"

@codecov
Copy link

codecov bot commented Jan 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.01%. Comparing base (3dc1cd6) to head (47a2602).
⚠️ Report is 239 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4498      +/-   ##
==========================================
- Coverage   99.21%   99.01%   -0.21%     
==========================================
  Files          42       46       +4     
  Lines        3182     3042     -140     
==========================================
- Hits         3157     3012     -145     
- Misses         17       20       +3     
- Partials        8       10       +2     
Flag Coverage Δ
?
--ldflags="-checklinkname=0" -tags sonic 99.00% <100.00%> (?)
-tags go_json 98.87% <100.00%> (?)
-tags nomsgpack 98.93% <100.00%> (?)
go-1.18 ?
go-1.19 ?
go-1.20 ?
go-1.21 ?
go-1.24 98.94% <100.00%> (?)
go-1.25 99.01% <100.00%> (?)
macos-latest 98.94% <100.00%> (-0.27%) ⬇️
ubuntu-latest 99.01% <100.00%> (-0.21%) ⬇️

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

☔ View full report in Codecov by Sentry.
📢 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.

@appleboy
Copy link
Member

@NyaaaWhatsUpDoc Please fix the conflicts.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes form binding so that slice fields correctly distinguish between "parameter not present" (nil slice) and "parameter present but empty" (non-nil, zero-length slice), including when defaults and collection_format are involved.

Changes:

  • Adjusted setByForm slice handling to treat vs == nil (no key) differently from len(vs) == 0 (key present but empty), and to only apply defaults when the field is absent.
  • Updated default-value handling for slices and arrays with collection_format tags to keep existing semantics while integrating the new nil vs empty behavior.
  • Expanded and updated TestMappingEmptyValues (and related collection format tests) to assert the new behavior for slices with/without defaults and with collection formats.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
binding/form_mapping.go Refines slice and array form-binding logic to differentiate missing vs empty values, and correctly construct default vs based on collection_format.
binding/form_mapping_test.go Updates expectations and adds coverage to verify nil vs empty slice behavior across defaulted, non-defaulted, and collection-format scenarios.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@NyaaaWhatsUpDoc NyaaaWhatsUpDoc force-pushed the bugfix/form-array-binding-regression branch from f2443d1 to 47a2602 Compare February 5, 2026 19:18
@NyaaaWhatsUpDoc
Copy link
Author

@appleboy merge conflicts fixed!

FileData []customPathUnmarshalText `form:"path,default=bar/foo;bar/foo/spam,parser=encoding.TextUnmarshaler" collection_format:"csv"`
}
err := mappingByPtr(&s, formSource{"path": {}}, "form")
err := mappingByPtr(&s, formSource{"path": nil}, "form")
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

previously this was relying on an empty (but not nil!) value slice to rely on default, but an empty slice isn't the zero value. a nil slice is.

FileData []objectIDUnmarshalText `form:"ids,default=664a062ac74a8ad104e0e80e;664a062ac74a8ad104e0e80f,parser=encoding.TextUnmarshaler" collection_format:"csv"`
}
err := mappingByPtr(&s, formSource{"ids": {}}, "form")
err := mappingByPtr(&s, formSource{"ids": nil}, "form")
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

previously this was relying on an empty (but not nil!) value slice to rely on default, but an empty slice isn't the zero value. a nil slice is.

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