Skip to content

Commit 629a919

Browse files
committed
CScript.is_witness_scriptpubkey : size must match second byte + 2
Model CScript.is_witness_scriptpubkey after bitcoind's CScript::IsWitnessProgram -- it not only checks for script size and first opcode, but also checks that data push size equals script size + 2 (entire script consists of version byte and data push). In absense of this check, is_witness_scriptpubkey wrongfully detects 1-of-1 p2sh redeem script as a witness program.
1 parent 05cbb3c commit 629a919

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

bitcoin/core/script.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -678,9 +678,23 @@ def is_p2sh(self):
678678
_bord(self[22]) == OP_EQUAL)
679679

680680
def is_witness_scriptpubkey(self):
681-
"""Returns true if this is a scriptpubkey signaling segregated witness
682-
data. """
683-
return 3 <= len(self) <= 42 and CScriptOp(struct.unpack('<b',self[0:1])[0]).is_small_int()
681+
"""Returns true if this is a scriptpubkey signaling segregated witness data.
682+
683+
A witness program is any valid CScript that consists of a 1-byte push opcode
684+
followed by a data push between 2 and 40 bytes.
685+
"""
686+
size = len(self)
687+
if size < 4 or size > 42:
688+
return False
689+
690+
head = struct.unpack('<bb', self[:2])
691+
if not CScriptOp(head[0]).is_small_int():
692+
return False
693+
694+
if head[1] + 2 != size:
695+
return False
696+
697+
return True
684698

685699
def witness_version(self):
686700
"""Returns the witness version on [0,16]. """

0 commit comments

Comments
 (0)