Skip to content

fix: prevent silent wraparound in out-of-range numeric conversions - #368

Closed
AdamMagued wants to merge 1 commit into
spf13:masterfrom
AdamMagued:fix-numeric-conversion-bounds-overflow
Closed

AdamMagued wants to merge 1 commit into
spf13:masterfrom
AdamMagued:fix-numeric-conversion-bounds-overflow

Conversation

@AdamMagued

Copy link
Copy Markdown

Summary

Fixes #356

When converting typed numeric inputs (such as uint64(math.MaxUint64) or float64(1e300)), toNumber[T] directly executed unchecked Go conversions T(s) without verifying if the value fits the target representation. As a result:

  • Out-of-range unsigned integers wrapped to negative signed integers (e.g., ToInt64E(uint64(math.MaxUint64)) == -1, nil).
  • Out-of-range floats or NaN values converted to math.MinInt64 or wrapped with nil error due to implementation-defined float-to-int conversion behavior.
  • In contrast, equivalent values passed as strings through strconv were rejected with range errors.

Changes

  • Added range-fitting checks to toNumber and toUnsignedNumber before performing type conversions.
  • Implemented numberFitsFromInt64, numberFitsFromUint64, and numberFitsFromFloat64 helpers:
    • Validates value ranges for integer targets (including architecture-dependent int/uint sizes via strconv.IntSize).
    • Guards float-to-integer conversions against NaN, ±Inf, and overflow (f >= float64(1<<63) or f < float64(math.MinInt64) for int64).
    • Preserves integer truncation semantics for floats within representable bounds (e.g., -128.9 to -128).
    • Unconditionally permits integer/float conversions to float targets.
  • Added regression tests in cast_test.go covering out-of-range conversions for integers, floats, NaN, and ±Inf.

Verification

  • Run go test -v ./...: 100% passed.
  • Run go vet ./...: clean.

Add range bounds checking to toNumber and toUnsignedNumber before converting typed numeric values (e.g. uint64, float64). Previously, unchecked Go conversions directly evaluated T(s), causing out-of-range values such as uint64(math.MaxUint64) to wrap to -1 and float64(1e300) or NaN to yield math.MinInt64 with a nil error, inconsistent with string inputs which correctly returned range errors.

Introduce helper functions numberFitsFromInt64, numberFitsFromUint64, and numberFitsFromFloat64 to ensure values fit the target numeric type prior to conversion, returning an error when out-of-range. Add regression tests for typed numeric overflow and NaN conversions.

Fixes spf13#356
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@AdamMagued

Copy link
Copy Markdown
Author

Closing in favor of earlier community PR #357 to avoid duplicate review effort.

@AdamMagued AdamMagued closed this Oct 2, 2026
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.

Out-of-range numeric conversions silently wrap instead of erroring (ToInt64E(uint64max) == -1)

2 participants