Skip to content

fix: reject out-of-range typed numeric conversions instead of wrapping - #357

Open
haoku123 wants to merge 1 commit into
spf13:masterfrom
haoku123:fix/typed-numeric-overflow
Open

fix: reject out-of-range typed numeric conversions instead of wrapping#357
haoku123 wants to merge 1 commit into
spf13:masterfrom
haoku123:fix/typed-numeric-overflow

Conversation

@haoku123

Copy link
Copy Markdown

Description

Fixes #356: every To<Int>E / To<Uint>E conversion from a typed numeric value was an unchecked Go conversion. Out-of-range inputs wrapped silently and returned err == nil, while the same values arriving as strings were correctly rejected by strconv. The two paths disagreed.

Changes

Added range checks to the typed numeric fast paths:

  • toNumber (signed targets): each numeric source case verifies the value fits the target before converting; out-of-range values return ok=false and fall through to the existing error path.
  • toUnsignedNumber (unsigned targets): same upper-bound checks added on top of the existing negative-value rejection.
  • New helpers numberFitsFromInt64, numberFitsFromUint64, numberFitsFromFloat64:
    • reject NaN / ±Inf floats,
    • use exact 2^63 / 2^64 boundaries for 64-bit targets (float64 cannot represent MaxInt64),
    • allow truncation that lands inside the range (-128.9 → -128),
    • keep int/uint portable via strconv.IntSize,
    • float targets always fit (cast intentionally allows lossy int-to-float conversions).

Verification

Repro from the issue now errors for every case:

ToInt64E(uint64(MaxUint64))  → error (was -1, nil)
ToInt64E(float64(MaxInt64))  → error (was MinInt64, nil)
ToInt64E(1e300)              → error
ToInt64E(Inf)                → error
ToInt64E(NaN)                → error
ToInt8E(1e300)               → error (was 0, nil)
ToUint64E(NaN)               → error
  • In-range conversions unaffected: 42, 3.7 → 3, -128.9 → -128, uint64(7).
  • New tests: TestTypedNumericOverflow (11 overflow cases) + TestTypedNumericInRange.
  • Control experiment: removing one check makes the tests fail.
  • go test -count=1 ./... PASS, go vet ./... clean.

Every To<Int>E / To<Uint>E conversion from a typed numeric value used an
unchecked Go conversion: out-of-range inputs wrapped silently and
returned err == nil, while the same values arriving as strings were
correctly rejected by strconv.

Add range checks to the typed numeric fast paths in toNumber and
toUnsignedNumber so out-of-range values fall through to the error path
and the two paths agree.

Fixes spf13#356
@CLAassistant

CLAassistant commented Aug 14, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

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