Prevent asInt() from modifying stack data.
The stack data is normally sliced from the actual script and btcscript is not supposed to ever change the tx passed into it. Add a test (and fix the other leading zeros tests) to stop this happening again.
This commit is contained in:
parent
093ddbe193
commit
4e608c115f
2 changed files with 47 additions and 4 deletions
10
stack.go
10
stack.go
|
@ -19,10 +19,11 @@ func asInt(v []byte) *big.Int {
|
|||
if msb&0x80 == 0x80 {
|
||||
negative = true
|
||||
// remove sign bit
|
||||
v[len(v)-1] &= 0x7f
|
||||
msb &= 0x7f
|
||||
}
|
||||
start := 0
|
||||
// trim leading 0 bytes
|
||||
for ; msb == 0; msb = v[len(v)-1] {
|
||||
for ; msb == 0; msb, start = v[len(v)-1], start+1 {
|
||||
v = v[:len(v)-1]
|
||||
if len(v) == 0 {
|
||||
break
|
||||
|
@ -31,8 +32,13 @@ func asInt(v []byte) *big.Int {
|
|||
// reverse bytes with a copy since stack is immutable.
|
||||
intArray := make([]byte, len(v))
|
||||
for i := range v {
|
||||
// Mask off the sign bit without changing original array.
|
||||
if i == 0 && start == 0 && negative {
|
||||
intArray[len(v)-i -1] = v[i] & 0x7f
|
||||
} else {
|
||||
intArray[len(v)-i-1] = v[i]
|
||||
}
|
||||
}
|
||||
|
||||
num := new(big.Int).SetBytes(intArray)
|
||||
if negative {
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"bytes"
|
||||
"errors"
|
||||
"github.com/conformal/btcscript"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"testing"
|
||||
)
|
||||
|
@ -220,13 +221,14 @@ var stackTests = []stackTest{
|
|||
},
|
||||
{
|
||||
"popInt 1 leading 0",
|
||||
[][]byte{{0x00000001}},
|
||||
[][]byte{{0x01, 0x00, 0x00, 0x00}},
|
||||
func(stack *btcscript.Stack) error {
|
||||
v, err := stack.PopInt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if v.Cmp(big.NewInt(1)) != 0 {
|
||||
fmt.Printf("%v != %v\n", v, big.NewInt(1))
|
||||
return errors.New("1 != 1 on popInt")
|
||||
}
|
||||
return nil
|
||||
|
@ -234,6 +236,41 @@ var stackTests = []stackTest{
|
|||
nil,
|
||||
[][]byte{},
|
||||
},
|
||||
{
|
||||
"popInt -1 leading 0",
|
||||
[][]byte{{0x01,0x00, 0x00, 0x80}},
|
||||
func(stack *btcscript.Stack) error {
|
||||
v, err := stack.PopInt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if v.Cmp(big.NewInt(-1)) != 0 {
|
||||
fmt.Printf("%v != %v\n", v, big.NewInt(-1))
|
||||
return errors.New("-1 != -1 on popInt")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
nil,
|
||||
[][]byte{},
|
||||
},
|
||||
// Confirm that the asInt code doesn't modify the base data.
|
||||
{
|
||||
"peekint nomodify -1",
|
||||
[][]byte{{0x01,0x00, 0x00, 0x80}},
|
||||
func(stack *btcscript.Stack) error {
|
||||
v, err := stack.PeekInt(0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if v.Cmp(big.NewInt(-1)) != 0 {
|
||||
fmt.Printf("%v != %v\n", v, big.NewInt(-1))
|
||||
return errors.New("-1 != -1 on popInt")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
nil,
|
||||
[][]byte{{0x01,0x00, 0x00, 0x80}},
|
||||
},
|
||||
{
|
||||
"PushInt 0",
|
||||
[][]byte{},
|
||||
|
|
Loading…
Reference in a new issue