From d7603f72c1f8bbf62ce69d0e1d12decdd1463c40 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Thu, 3 Aug 2023 15:16:49 +0200 Subject: [PATCH] fastparse: Fix bug in overflow detection When we have an overflow here, we didn't always correctly detect this when we parse a value. The switch trick here makes the compiler see the very common case of base 10 (which we use most of the time by far) and turn the computation into a constant value. Signed-off-by: Dirkjan Bussink --- go/mysql/fastparse/fastparse.go | 28 ++++++++++++++++++++++++++++ go/mysql/fastparse/fastparse_test.go | 12 ++++++++++++ 2 files changed, 40 insertions(+) diff --git a/go/mysql/fastparse/fastparse.go b/go/mysql/fastparse/fastparse.go index 1296bf5866e..33aa16105c2 100644 --- a/go/mysql/fastparse/fastparse.go +++ b/go/mysql/fastparse/fastparse.go @@ -65,6 +65,18 @@ next: break next } + var cutoff uint64 + switch base { + case 10: + cutoff = math.MaxUint64/10 + 1 + case 16: + cutoff = math.MaxUint64/16 + 1 + default: + cutoff = math.MaxUint64/uint64(base) + 1 + } + if d >= cutoff { + return math.MaxUint64, fmt.Errorf("cannot parse uint64 from %q: %w", s, ErrOverflow) + } v := d*uint64(base) + uint64(b) if v < d { return math.MaxUint64, fmt.Errorf("cannot parse uint64 from %q: %w", s, ErrOverflow) @@ -139,6 +151,22 @@ next: break next } + var cutoff uint64 + switch base { + case 10: + cutoff = math.MaxInt64/10 + 1 + case 16: + cutoff = math.MaxInt64/16 + 1 + default: + cutoff = math.MaxInt64/uint64(base) + 1 + } + if d >= cutoff { + if minus { + return math.MinInt64, fmt.Errorf("cannot parse int64 from %q: %w", s, ErrOverflow) + } + return math.MaxInt64, fmt.Errorf("cannot parse int64 from %q: %w", s, ErrOverflow) + } + v := d*uint64(base) + uint64(b) if v < d { if minus { diff --git a/go/mysql/fastparse/fastparse_test.go b/go/mysql/fastparse/fastparse_test.go index f6477422459..bec312b0bb5 100644 --- a/go/mysql/fastparse/fastparse_test.go +++ b/go/mysql/fastparse/fastparse_test.go @@ -161,6 +161,12 @@ func TestParseInt64(t *testing.T) { expected: 9223372036854775807, err: `cannot parse int64 from "18446744073709551616": overflow`, }, + { + input: "31415926535897932384", + base: 10, + expected: 9223372036854775807, + err: `cannot parse int64 from "31415926535897932384": overflow`, + }, { input: "1.1", base: 10, @@ -297,6 +303,12 @@ func TestParseUint64(t *testing.T) { expected: 18446744073709551615, err: `cannot parse uint64 from "18446744073709551616": overflow`, }, + { + input: "31415926535897932384", + base: 10, + expected: 18446744073709551615, + err: `cannot parse uint64 from "31415926535897932384": overflow`, + }, { input: "1.1", base: 10,