]> Cypherpunks.ru repositories - gostls13.git/commitdiff
math/big: fix uint64 overflow in nat.mulRange
authorRobert Griesemer <gri@golang.org>
Mon, 8 Jan 2024 21:28:59 +0000 (13:28 -0800)
committerGopher Robot <gobot@golang.org>
Tue, 9 Jan 2024 15:29:36 +0000 (15:29 +0000)
Compute median as a + (b-a)/2 instead of (a + b)/2.
Add additional test cases.

Fixes #65025.

Change-Id: Ib716a1036c17f8f33f51e33cedab13512eb7e0be
Reviewed-on: https://go-review.googlesource.com/c/go/+/554617
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Robert Griesemer <gri@google.com>
Reviewed-by: Rob Pike <r@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
src/math/big/int_test.go
src/math/big/nat.go
src/math/big/nat_test.go

index cb964a43cd2fa05faac34a74f5c8a18826705cc6..088bce09f9169ca8bb84e9ffcbf54642a902f384 100644 (file)
@@ -200,12 +200,22 @@ var mulRangesZ = []struct {
                        "638952175999932299156089414639761565182862536979208272237582" +
                        "511852109168640000000000000000000000", // -99!
        },
+
+       // overflow situations
+       {math.MaxInt64 - 0, math.MaxInt64, "9223372036854775807"},
+       {math.MaxInt64 - 1, math.MaxInt64, "85070591730234615838173535747377725442"},
+       {math.MaxInt64 - 2, math.MaxInt64, "784637716923335094969050127519550606919189611815754530810"},
+       {math.MaxInt64 - 3, math.MaxInt64, "7237005577332262206126809393809643289012107973151163787181513908099760521240"},
 }
 
 func TestMulRangeZ(t *testing.T) {
        var tmp Int
        // test entirely positive ranges
        for i, r := range mulRangesN {
+               // skip mulRangesN entries that overflow int64
+               if int64(r.a) < 0 || int64(r.b) < 0 {
+                       continue
+               }
                prod := tmp.MulRange(int64(r.a), int64(r.b)).String()
                if prod != r.prod {
                        t.Errorf("#%da: got %s; want %s", i, prod, r.prod)
index b9f4026a04dc0b9c59f7ab67c41e04c99a3749e0..ecb7d363d4fb368915eb64a857e53253e304e266 100644 (file)
@@ -624,7 +624,7 @@ func (z nat) mulRange(a, b uint64) nat {
        case a+1 == b:
                return z.mul(nat(nil).setUint64(a), nat(nil).setUint64(b))
        }
-       m := (a + b) / 2
+       m := a + (b-a)/2 // avoid overflow
        return z.mul(nat(nil).mulRange(a, m), nat(nil).mulRange(m+1, b))
 }
 
index b84a7be5bcbcac0ec81e92d12c4a9662b364ec2a..4722548fa965faafc0fdd0549888a90b9d7a7528 100644 (file)
@@ -6,6 +6,7 @@ package big
 
 import (
        "fmt"
+       "math"
        "runtime"
        "strings"
        "testing"
@@ -155,6 +156,10 @@ var mulRangesN = []struct {
                        "638952175999932299156089414639761565182862536979208272237582" +
                        "51185210916864000000000000000000000000", // 100!
        },
+       {math.MaxUint64 - 0, math.MaxUint64, "18446744073709551615"},
+       {math.MaxUint64 - 1, math.MaxUint64, "340282366920938463408034375210639556610"},
+       {math.MaxUint64 - 2, math.MaxUint64, "6277101735386680761794095221682035635525021984684230311930"},
+       {math.MaxUint64 - 3, math.MaxUint64, "115792089237316195360799967654821100226821973275796746098729803619699194331160"},
 }
 
 func TestMulRangeN(t *testing.T) {