Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
txscript: Match Bitcoin Core OP_IFDUP behavior.
Unlike OP_IF and OP_NOTIF which interpret the top stack item as a
number, OP_IFDUP interprets it as a boolean.  This has important
consequences because numbers are imited to int32s while booleans can be
an arbitrary number of bytes.

The offending script was found and reported by Jonas Nick through the
use of fuzzing.
  • Loading branch information
davecgh committed May 5, 2015
1 parent 6801c00 commit f284b9b
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 3 deletions.
1 change: 1 addition & 0 deletions txscript/data/script_valid.json
Expand Up @@ -80,6 +80,7 @@

["0 IFDUP", "DEPTH 1 EQUALVERIFY 0 EQUAL", "P2SH,STRICTENC"],
["1 IFDUP", "DEPTH 2 EQUALVERIFY 1 EQUALVERIFY 1 EQUAL", "P2SH,STRICTENC"],
["0x05 0x0100000000 IFDUP", "DEPTH 2 EQUALVERIFY 0x05 0x0100000000 EQUAL", "P2SH,STRICTENC", "IFDUP dups non ints"],
["0 DROP", "DEPTH 0 EQUAL", "P2SH,STRICTENC"],
["0", "DUP 1 ADD 1 EQUALVERIFY 0 EQUAL", "P2SH,STRICTENC"],
["0 1", "NIP", "P2SH,STRICTENC"],
Expand Down
6 changes: 3 additions & 3 deletions txscript/opcode.go
Expand Up @@ -1084,14 +1084,14 @@ func opcode2Swap(op *parsedOpcode, vm *Engine) error {
// Stack transformation (x1==0): [... x1] -> [...]
// Stack transformation (x1!=0): [... x1] -> [... x1]
func opcodeIfDup(op *parsedOpcode, vm *Engine) error {
val, err := vm.dstack.PeekInt(0)
so, err := vm.dstack.PeekByteArray(0)
if err != nil {
return err
}

// Push copy of data iff it isn't zero
if val != 0 {
vm.dstack.PushInt(val)
if asBool(so) {
vm.dstack.PushByteArray(so)
}

return nil
Expand Down

0 comments on commit f284b9b

Please sign in to comment.