Skip to content

Commit c7e55c0

Browse files
committed
fix(bytesconv): detect integer overflow before multiplication in ParseUintBuf
ParseUintBuf checked for overflow after computing 10*v + k. When 10*v itself overflows, the wrapped result can still be greater than v, so the check silently passed and the function returned a wrapped value instead of errTooLongInt. Move the check before the multiplication so out-of-range input is rejected consistently. Reuses the existing errTooLongInt and keeps the function signature unchanged. Add the previously missed inputs to TestParseUintError.
1 parent 3415de4 commit c7e55c0

2 files changed

Lines changed: 12 additions & 4 deletions

File tree

internal/bytesconv/bytesconv.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
package bytesconv
4343

4444
import (
45+
"math"
4546
"net/http"
4647
"time"
4748
"unsafe"
@@ -162,12 +163,13 @@ func ParseUintBuf(b []byte) (int, int, error) {
162163
}
163164
return v, i, nil
164165
}
165-
vNew := 10*v + int(k)
166-
// Test for overflow.
167-
if vNew < v {
166+
// Test for overflow before multiplying, because 10*v may wrap around
167+
// to a value that is still greater than v, which would make a
168+
// post-multiplication check unreliable.
169+
if v > (math.MaxInt-int(k))/10 {
168170
return -1, i, errTooLongInt
169171
}
170-
v = vNew
172+
v = 10*v + int(k)
171173
}
172174
return v, n, nil
173175
}

internal/bytesconv/bytesconv_64_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ func TestParseUintError(t *testing.T) {
104104
{"-9223372036854775808"},
105105
{"9223372036854775808"},
106106
{"18446744073709551615"},
107+
// Values whose intermediate 10*v wraps past 2^64 and lands back on a
108+
// positive number, which a post-multiplication overflow check misses.
109+
{"21000000000000000000"},
110+
{"25000000000000000000"},
111+
{"46000000000000000000"},
112+
{"83000000000000000000"},
107113
} {
108114
n, err := ParseUint(S2b(v.s))
109115
if err == nil {

0 commit comments

Comments
 (0)