From a5e7e9ebb669e09f2abb0783c635f4d340b11ff4 Mon Sep 17 00:00:00 2001 From: "Owain G. Ainsworth" Date: Fri, 14 Mar 2014 17:20:51 +0000 Subject: [PATCH] Disabled opcodes are `fail if pc passes' not fail if execute. Detected by bitcoind negative tests. --- opcode.go | 39 +++++++++++++++++++++++++++++++++++++++ script.go | 4 +++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/opcode.go b/opcode.go index 3b26b329..58ec7367 100644 --- a/opcode.go +++ b/opcode.go @@ -862,6 +862,45 @@ type parsedOpcode struct { opfunc func(op parsedOpcode, s Script) error } +// The following opcodes are disabled and are thus always bad to see in the +// instruction stream (even if turned off by a conditional). +func (pop *parsedOpcode) disabled() bool { + switch pop.opcode.value { + case OP_CAT: + return true + case OP_SUBSTR: + return true + case OP_LEFT: + return true + case OP_RIGHT: + return true + case OP_INVERT: + return true + case OP_AND: + return true + case OP_OR: + return true + case OP_XOR: + return true + case OP_2MUL: + return true + case OP_2DIV: + return true + case OP_MUL: + return true + case OP_DIV: + return true + case OP_MOD: + return true + case OP_LSHIFT: + return true + case OP_RSHIFT: + return true + default: + return false + } +} + // The following opcodes are always illegal when passed over by the program // counter even if in a non-executed branch. (it isn't a coincidence that they // are conditionals). diff --git a/script.go b/script.go index 23e1fdf5..528969bc 100644 --- a/script.go +++ b/script.go @@ -603,7 +603,9 @@ func (m *Script) Step() (done bool, err error) { if m.condStack[0] != OpCondTrue { // some opcodes still 'activate' if on the non-executing side // of conditional execution - if opcode.alwaysIllegal() { + if opcode.disabled() { + return true, StackErrOpDisabled + } else if opcode.alwaysIllegal() { return true, StackErrAlwaysIllegal } else if opcode.conditional() { executeInstr = true