Skip to content

fix(spec): keep zero-valued bounds through a gob round-trip - #310

Merged
fredbi merged 1 commit into
go-openapi:masterfrom
fredbi:fix/gob-drops-zero-valued-bounds
Aug 25, 2026
Merged

fix(spec): keep zero-valued bounds through a gob round-trip#310
fredbi merged 1 commit into
go-openapi:masterfrom
fredbi:fix/gob-drops-zero-valued-bounds

Conversation

@fredbi

@fredbi fredbi commented Aug 25, 2026

Copy link
Copy Markdown
Member

gob omits any struct field holding the zero value for its type, and flattens a pointer to the value it points at. An optional number that is present and zero travelled as the zero value, was omitted, and came back as a nil pointer: "minimum": 0 on a schema, "maximum": 0 on a parameter and every other bound spelled with a zero were dropped, with no error. Encoding a whole Swagger lost them at any depth, through the encoder this package already advertises.

Schema, Parameter, Header and Items now send which of their optional numbers were present-and-zero as a bitmask alongside the struct, and put the zero back on decode. The encoders sit on those outer types rather than on CommonValidations or SchemaProps because a method on an embedded type is promoted to whatever embeds it: gob would call it for the whole value and drop everything the embedded type does not hold. Swagger and Operation already carry their own encoders for that reason.

TestGob_EveryOptionalNumberIsCarried reads the *float64 and *int64 fields of those four types by reflection, so a bound added later is covered without editing the test, and fails until gob.go carries it.

Round-tripping a mid-sized document through gob costs 153ms and 92MB against 47ms and 26MB before this change, because a GobEncode that returns bytes needs its own encoder per value. JSON round-trips the same document in 39ms and 12MB, so gob is the slower way to copy this model either way.

Change type

Please select: 🆕 New feature or enhancement|🔧 Bug fix'|📃 Documentation update

Short description

Fixes

Full description

Checklist

  • I have signed all my commits with my name and email (see DCO. This does not require a PGP-signed commit
  • I have rebased and squashed my work, so only one commit remains
  • I have added tests to cover my changes.
  • I have properly enriched go doc comments in code.
  • I have properly documented any breaking change.

gob omits any struct field holding the zero value for its type, and
flattens a pointer to the value it points at. An optional number that is
present and zero travelled as the zero value, was omitted, and came back
as a nil pointer: "minimum": 0 on a schema, "maximum": 0 on a parameter
and every other bound spelled with a zero were dropped, with no error.
Encoding a whole Swagger lost them at any depth, through the encoder this
package already advertises.

Schema, Parameter, Header and Items now send which of their optional
numbers were present-and-zero as a bitmask alongside the struct, and put
the zero back on decode. The encoders sit on those outer types rather
than on CommonValidations or SchemaProps because a method on an embedded
type is promoted to whatever embeds it: gob would call it for the whole
value and drop everything the embedded type does not hold. Swagger and
Operation already carry their own encoders for that reason.

TestGob_EveryOptionalNumberIsCarried reads the *float64 and *int64
fields of those four types by reflection, so a bound added later is
covered without editing the test, and fails until gob.go carries it.

Round-tripping a mid-sized document through gob costs 153ms and 92MB
against 47ms and 26MB before this change, because a GobEncode that
returns bytes needs its own encoder per value. JSON round-trips the same
document in 39ms and 12MB, so gob is the slower way to copy this model
either way.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
@codecov

codecov Bot commented Aug 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.66667% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.19%. Comparing base (69a6c4c) to head (0812163).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
gob.go 96.66% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #310      +/-   ##
==========================================
+ Coverage   93.03%   93.19%   +0.16%     
==========================================
  Files          30       31       +1     
  Lines        2512     2632     +120     
==========================================
+ Hits         2337     2453     +116     
- Misses        175      179       +4     

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

@fredbi
fredbi merged commit f0e1e04 into go-openapi:master Aug 25, 2026
24 checks passed
@fredbi
fredbi deleted the fix/gob-drops-zero-valued-bounds branch August 25, 2026 19:28
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.

1 participant