aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Peppe <rogpeppe@gmail.com>2011-11-30 09:29:58 -0800
committerRobert Griesemer <gri@golang.org>2011-11-30 09:29:58 -0800
commitca6de008bae698dd79adf795cd24668f36578d77 (patch)
treeafad312eeede73bad6c8ab9ea5d64ec31368cdd2
parent8dce57e169255608b46bb563bb7de1581908aea6 (diff)
downloadgo-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.go8
-rw-r--r--src/pkg/math/big/nat.go6
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