Skip to content

fix: read float-tagged int64 schema keywords instead of storing 0 - #666

Open
TastyHeadphones wants to merge 1 commit into
pb33f:mainfrom
TastyHeadphones:fix/int64-float-keywords
Open

TastyHeadphones wants to merge 1 commit into
pb33f:mainfrom
TastyHeadphones:fix/int64-float-keywords

Conversation

@TastyHeadphones

Copy link
Copy Markdown

Fixes #665

setFieldNodeReferenceInt64Type accepts int and float nodes, but parsed the value with strconv.ParseInt(..., 10, 64) and ignored the error. A float such as maxLength: 2.0 or maxItems: 1.7976931348623157E+308 therefore became 0, so a validator built on the model rejected every non-empty string or array.

Changes in datamodel/low/model_builder.go:

  • new parseInt64Node helper, used by the NodeReference[int64] and []NodeReference[int64] cases
  • integer text is parsed as before, including ParseInt's clamping of out-of-range integers to math.MaxInt64 / math.MinInt64
  • a whole-number float is converted (2.0 → 2, 1e3 → 1000)
  • a float at or beyond ±2^63, and YAML .inf / -.inf, clamps to math.MaxInt64 / math.MinInt64, the same as ParseInt does for an out-of-range integer
  • a fraction (2.5) or .nan leaves the field unset, so the high-level pointer stays nil instead of pointing at 0. JSON Schema requires these keywords to be non-negative integers, so such a schema is invalid anyway. If you'd prefer a different behaviour for fractions (e.g. rounding), it's a one-line change.
  • slice items keep the old fallback of 0 when they don't parse

Tests:

  • TestBuildModel_Int64FromFloatAndRange / TestBuildModel_Int64SliceFromFloat in datamodel/low/model_builder_test.go cover the parse cases through BuildModel
  • issue665_test.go reproduces the report through NewDocument + BuildV3Model (2.0 → 2, 1.7976931348623157E+308 → math.MaxInt64, 5 → 5, 2.5 → nil)

Both new tests fail on main and pass with this change. go vet is clean, and go test ./... passes except FuzzAppendJSONString/seed#5 in ./json, which also fails on main with my local Go 1.27.2 (it's about \ufffd escaping and unrelated to this change).

AI disclosure: Grok (xAI) wrote the first draft of this change and its tests. I reviewed it, simplified the helper's .inf handling, and ran the tests myself. I'm responsible for the change.

maxLength, minLength, maxItems, minItems, maxProperties and minProperties
accept int and float nodes, but the value was parsed with strconv.ParseInt
and the error ignored, so 2.0 or 1.7976931348623157E+308 became 0.

Whole-number floats are now converted, floats at or beyond the int64 range
(and .inf / -.inf) clamp to math.MaxInt64 / math.MinInt64 like ParseInt
does for out-of-range integers, and fractions or NaN leave the field unset.

Fixes pb33f#665
@codecov

codecov Bot commented Oct 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (e0e2f84) to head (d9afd99).

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #666   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          309       309           
  Lines        39178     39198   +20     
=========================================
+ Hits         39178     39198   +20     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

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.

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.

A float-tagged count keyword (maxLength: 2.0, maxItems: 1.7976931348623157E+308) is read as 0

1 participant