Skip to content

Commit

Permalink
Return scriptPos in checkParseableInScript
Browse files Browse the repository at this point in the history
  • Loading branch information
Rjected committed Dec 16, 2020
1 parent cfbc874 commit fe077fe
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 12 deletions.
17 changes: 9 additions & 8 deletions txscript/opcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,8 @@ func (pop *parsedOpcode) isDisabled() bool {

// checkParseableInScript checks whether or not the current opcode is able to be
// parsed at a certain position in a script.
func (pop *parsedOpcode) checkParseableInScript(script []byte, scriptPos int) (error) {
// This returns the position of the next opcode to be parsed in the script.
func (pop *parsedOpcode) checkParseableInScript(script []byte, scriptPos int) (int, error) {
// Parse data out of instruction.
switch {
// No additional data. Note that some of the opcodes, notably
Expand All @@ -673,7 +674,7 @@ func (pop *parsedOpcode) checkParseableInScript(script []byte, scriptPos int) (e
str := fmt.Sprintf("opcode %s requires %d "+
"bytes, but script only has %d remaining",
pop.opcode.name, pop.opcode.length, len(script[scriptPos:]))
return scriptError(ErrMalformedPush, str)
return 0, scriptError(ErrMalformedPush, str)
}

// Slice out the data.
Expand All @@ -685,11 +686,11 @@ func (pop *parsedOpcode) checkParseableInScript(script []byte, scriptPos int) (e
var l uint
off := scriptPos + 1

if len(script[off:]) < - pop.opcode.length {
if len(script[off:]) < -pop.opcode.length {
str := fmt.Sprintf("opcode %s requires %d "+
"bytes, but script only has %d remaining",
pop.opcode.name, - pop.opcode.length, len(script[off:]))
return scriptError(ErrMalformedPush, str)
pop.opcode.name, -pop.opcode.length, len(script[off:]))
return 0, scriptError(ErrMalformedPush, str)
}

// Next -length bytes are little endian length of data.
Expand All @@ -707,7 +708,7 @@ func (pop *parsedOpcode) checkParseableInScript(script []byte, scriptPos int) (e
default:
str := fmt.Sprintf("invalid opcode length %d",
pop.opcode.length)
return scriptError(ErrMalformedPush, str)
return 0, scriptError(ErrMalformedPush, str)
}

// Move offset to beginning of the data.
Expand All @@ -719,13 +720,13 @@ func (pop *parsedOpcode) checkParseableInScript(script []byte, scriptPos int) (e
str := fmt.Sprintf("opcode %s pushes %d bytes, "+
"but script only has %d remaining",
pop.opcode.name, int(l), len(script[off:]))
return scriptError(ErrMalformedPush, str)
return 0, scriptError(ErrMalformedPush, str)
}

pop.data = script[off : off+int(l)]
scriptPos += 1 - pop.opcode.length + int(l)
}
return nil
return scriptPos, nil
}

// alwaysIllegal returns whether or not the opcode is always illegal when passed
Expand Down
7 changes: 5 additions & 2 deletions txscript/script.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,12 @@ func IsPushOnlyScript(script []byte) bool {
// the list of parsed opcodes up to the point of failure along with the error.
func parseScriptTemplate(script []byte, opcodes *[256]opcode) ([]parsedOpcode, error) {
retScript := make([]parsedOpcode, 0, len(script))
var err error
for i := 0; i < len(script); {
instr := script[i]
op := &opcodes[instr]
pop := parsedOpcode{opcode: op}
err := pop.checkParseableInScript(script, i)
i, err = pop.checkParseableInScript(script, i)
if err != nil {
return retScript, err
}
Expand All @@ -223,6 +224,8 @@ func parseScriptTemplate(script []byte, opcodes *[256]opcode) ([]parsedOpcode, e
// Not returning the full opcode list up until failure also has the benefit of
// reducing GC pressure, as the list would get immediately thrown away.
func checkScriptTemplateParseable(script []byte, opcodes *[256]opcode) (*byte, error) {
var err error

// A script of length zero is an unspendable script but it is parseable.
var firstOpcode byte
var numParsedInstr uint = 0
Expand All @@ -231,7 +234,7 @@ func checkScriptTemplateParseable(script []byte, opcodes *[256]opcode) (*byte, e
instr := script[i]
op := &opcodes[instr]
pop := parsedOpcode{opcode: op}
err := pop.checkParseableInScript(script, i)
i, err = pop.checkParseableInScript(script, i)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions txscript/script_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4315,12 +4315,12 @@ func TestIsUnspendable(t *testing.T) {
},
{
// Spendable
pkScript: []byte{0x51},
pkScript: []byte{OP_TRUE},
expected: false,
},
{
// Unspendable
pkScript: []byte{0x6a},
pkScript: []byte{OP_RETURN},
expected: true,
},
}
Expand Down

0 comments on commit fe077fe

Please sign in to comment.