diff options
author | Roger Peppe <rogpeppe@gmail.com> | 2011-11-30 09:29:58 -0800 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2011-11-30 09:29:58 -0800 |
commit | ca6de008bae698dd79adf795cd24668f36578d77 (patch) | |
tree | afad312eeede73bad6c8ab9ea5d64ec31368cdd2 | |
parent | 8dce57e169255608b46bb563bb7de1581908aea6 (diff) | |
download | go-ca6de008bae698dd79adf795cd24668f36578d77.tar.gz go-ca6de008bae698dd79adf795cd24668f36578d77.zip |
math/big: fix destination leak into result value
This code would panic:
z := big.NewInt(1)
z.SetBit(big.NewInt(0), 2, 1)
if z.Cmp(big.NewInt(1<<2)) != 0 {
panic("fail")
}
R=rsc, gri
CC=golang-dev
https://golang.org/cl/5437081
-rw-r--r-- | src/pkg/math/big/int_test.go | 8 | ||||
-rw-r--r-- | src/pkg/math/big/nat.go | 6 |
2 files changed, 10 insertions, 4 deletions
diff --git a/src/pkg/math/big/int_test.go b/src/pkg/math/big/int_test.go index 163c662b0b..aa7c194954 100644 --- a/src/pkg/math/big/int_test.go +++ b/src/pkg/math/big/int_test.go @@ -1242,10 +1242,14 @@ func TestBitSet(t *testing.T) { x.SetString(test.x, 0) b := x.Bit(test.i) if b != test.b { - - t.Errorf("#%d want %v got %v", i, test.b, b) + t.Errorf("#%d got %v want %v", i, b, test.b) } } + z := NewInt(1) + z.SetBit(NewInt(0), 2, 1) + if z.Cmp(NewInt(4)) != 0 { + t.Errorf("destination leaked into result; got %s want 4", z) + } } func BenchmarkBitset(b *testing.B) { diff --git a/src/pkg/math/big/nat.go b/src/pkg/math/big/nat.go index 9fba2d2a06..680445dc9a 100644 --- a/src/pkg/math/big/nat.go +++ b/src/pkg/math/big/nat.go @@ -1065,9 +1065,11 @@ func (z nat) setBit(x nat, i uint, b uint) nat { return z.norm() case 1: if j >= n { - n = j + 1 + z = z.make(j + 1) + z[n:].clear() + } else { + z = z.make(n) } - z = z.make(n) copy(z, x) z[j] |= m // no need to normalize |