From 3e27d8ebad7a69e49e447c7d0511dda63a9fbabb Mon Sep 17 00:00:00 2001 From: Ivan Mironov Date: Thu, 23 Apr 2020 18:08:07 +0500 Subject: [PATCH] Fix integer overflow handling in parseUintBuf() (#789) * Add more tests for parseUintBuf() * Fix integer overflow handling in parseUintBuf() --- bytesconv.go | 5 +++-- bytesconv_32_test.go | 12 ++++++++++++ bytesconv_64_test.go | 11 +++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/bytesconv.go b/bytesconv.go index a3b82e2..222435a 100644 --- a/bytesconv.go +++ b/bytesconv.go @@ -185,11 +185,12 @@ func parseUintBuf(b []byte) (int, int, error) { } return v, i, nil } + vNew := 10*v + int(k) // Test for overflow. - if v*10 < v { + if vNew < v { return -1, i, errTooLongInt } - v = 10*v + int(k) + v = vNew } return v, n, nil } diff --git a/bytesconv_32_test.go b/bytesconv_32_test.go index 405230b..f0647bd 100644 --- a/bytesconv_32_test.go +++ b/bytesconv_32_test.go @@ -38,10 +38,22 @@ func TestReadHexIntSuccess(t *testing.T) { testReadHexIntSuccess(t, "1234ZZZ", 0x1234) } +func TestParseUintError32(t *testing.T) { + t.Parallel() + + // Overflow by last digit: 2 ** 32 / 2 * 10 ** n + testParseUintError(t, "2147483648") + testParseUintError(t, "21474836480") + testParseUintError(t, "214748364800") +} + func TestParseUintSuccess(t *testing.T) { t.Parallel() testParseUintSuccess(t, "0", 0) testParseUintSuccess(t, "123", 123) testParseUintSuccess(t, "123456789", 123456789) + + // Max supported value: 2 ** 32 / 2 - 1 + testParseUintSuccess(t, "2147483647", 2147483647) } diff --git a/bytesconv_64_test.go b/bytesconv_64_test.go index 1ba3237..d65f34f 100644 --- a/bytesconv_64_test.go +++ b/bytesconv_64_test.go @@ -39,6 +39,15 @@ func TestReadHexIntSuccess(t *testing.T) { testReadHexIntSuccess(t, "7ffffffffffffff", 0x7ffffffffffffff) } +func TestParseUintError64(t *testing.T) { + t.Parallel() + + // Overflow by last digit: 2 ** 64 / 2 * 10 ** n + testParseUintError(t, "9223372036854775808") + testParseUintError(t, "92233720368547758080") + testParseUintError(t, "922337203685477580800") +} + func TestParseUintSuccess(t *testing.T) { t.Parallel() @@ -46,5 +55,7 @@ func TestParseUintSuccess(t *testing.T) { testParseUintSuccess(t, "123", 123) testParseUintSuccess(t, "1234567890", 1234567890) testParseUintSuccess(t, "123456789012345678", 123456789012345678) + + // Max supported value: 2 ** 64 / 2 - 1 testParseUintSuccess(t, "9223372036854775807", 9223372036854775807) }