From f284b9b3947eb33b91e31deec74936855feed61f Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sat, 2 May 2015 22:53:37 -0500 Subject: [PATCH] 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. --- txscript/data/script_valid.json | 1 + txscript/opcode.go | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/txscript/data/script_valid.json b/txscript/data/script_valid.json index 064dde846..0dd9d2174 100644 --- a/txscript/data/script_valid.json +++ b/txscript/data/script_valid.json @@ -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"], diff --git a/txscript/opcode.go b/txscript/opcode.go index 8245151b0..7781465da 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -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