mirror of
https://github.com/btcsuite/btcd.git
synced 2025-03-13 11:35:52 +01:00
Merge 1048f476d0
into cba88226f4
This commit is contained in:
commit
4931cdf595
2 changed files with 60 additions and 13 deletions
|
@ -504,25 +504,51 @@ func isNullDataScript(scriptVersion uint16, script []byte) bool {
|
|||
// A null script is of the form:
|
||||
// OP_RETURN <optional data>
|
||||
//
|
||||
// Thus, it can either be a single OP_RETURN or an OP_RETURN followed by a
|
||||
// data push up to MaxDataCarrierSize bytes.
|
||||
// The entire scriptPubKey, including OP_RETURN and the payload, must not
|
||||
// exceed 83 bytes by default.
|
||||
|
||||
// The script can't possibly be a null data script if it doesn't start
|
||||
// with OP_RETURN. Fail fast to avoid more work below.
|
||||
const MaxScriptPubKeySize = 83
|
||||
|
||||
// Check if the script size exceeds the maximum allowed size.
|
||||
if len(script) > MaxScriptPubKeySize {
|
||||
return false
|
||||
}
|
||||
|
||||
// The script must start with OP_RETURN.
|
||||
if len(script) < 1 || script[0] != OP_RETURN {
|
||||
return false
|
||||
}
|
||||
|
||||
// Single OP_RETURN.
|
||||
// Single OP_RETURN (no payload).
|
||||
if len(script) == 1 {
|
||||
return true
|
||||
}
|
||||
|
||||
// OP_RETURN followed by data push up to MaxDataCarrierSize bytes.
|
||||
// Tokenize and validate the script after OP_RETURN.
|
||||
tokenizer := MakeScriptTokenizer(scriptVersion, script[1:])
|
||||
return tokenizer.Next() && tokenizer.Done() &&
|
||||
(IsSmallInt(tokenizer.Opcode()) || tokenizer.Opcode() <= OP_PUSHDATA4) &&
|
||||
len(tokenizer.Data()) <= MaxDataCarrierSize
|
||||
for tokenizer.Next() {
|
||||
opcode := tokenizer.Opcode()
|
||||
|
||||
// Allow small integer opcodes (OP_1 to OP_16).
|
||||
if IsSmallInt(opcode) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Allow valid data pushes.
|
||||
if opcode <= OP_PUSHDATA4 {
|
||||
// Ensure each data push is valid and within limits.
|
||||
if len(tokenizer.Data()) > MaxDataCarrierSize {
|
||||
return false
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Any other opcode is invalid for a null data script.
|
||||
return false
|
||||
}
|
||||
|
||||
// Ensure the tokenizer successfully parsed the entire script.
|
||||
return tokenizer.Done()
|
||||
}
|
||||
|
||||
// scriptType returns the type of the script being inspected from the known
|
||||
|
|
|
@ -1032,11 +1032,10 @@ var scriptClassTests = []struct {
|
|||
class: NonStandardTy,
|
||||
},
|
||||
{
|
||||
// Almost nulldata, but add an additional opcode after the data
|
||||
// to make it nonstandard.
|
||||
name: "almost nulldata",
|
||||
// nulldata, with combinations of op_code and pushdata
|
||||
name: "nulldata with multiple pushes",
|
||||
script: "RETURN 4 TRUE",
|
||||
class: NonStandardTy,
|
||||
class: NullDataTy,
|
||||
},
|
||||
|
||||
// The next few are almost multisig (it is the more complex script type)
|
||||
|
@ -1277,6 +1276,28 @@ func TestNullDataScript(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestIsNullDataScript(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
data []byte
|
||||
expectedIsNullData bool
|
||||
}{{
|
||||
name: "multiple pushes",
|
||||
data: hexToBytes("6a5d0f160100e6a233fc078088a5a9a30700"),
|
||||
expectedIsNullData: true,
|
||||
},
|
||||
}
|
||||
for i, test := range tests {
|
||||
isNullData := isNullDataScript(0, test.data)
|
||||
if isNullData != test.expectedIsNullData {
|
||||
t.Errorf("IsNullDataScript: #%d (%s) wrong result -- "+
|
||||
"got: %v, want: %v", i, test.name, isNullData,
|
||||
test.expectedIsNullData)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestNewScriptClass tests whether NewScriptClass returns a valid ScriptClass.
|
||||
func TestNewScriptClass(t *testing.T) {
|
||||
tests := []struct {
|
||||
|
|
Loading…
Add table
Reference in a new issue