txscript: Remove unused parseScriptTemplate func.
Also remove tests associated with the func accordingly.
This commit is contained in:
parent
4bbfd2413c
commit
6f3f4c1b8c
3 changed files with 0 additions and 148 deletions
|
@ -618,79 +618,6 @@ type parsedOpcode struct {
|
||||||
data []byte
|
data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkParseableInScript checks whether or not the current opcode is able to be
|
|
||||||
// parsed at a certain position in a script.
|
|
||||||
// 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
|
|
||||||
// OP_1NEGATE, OP_0, and OP_[1-16] represent the data
|
|
||||||
// themselves.
|
|
||||||
case pop.opcode.length == 1:
|
|
||||||
scriptPos++
|
|
||||||
|
|
||||||
// Data pushes of specific lengths -- OP_DATA_[1-75].
|
|
||||||
case pop.opcode.length > 1:
|
|
||||||
if len(script[scriptPos:]) < 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[scriptPos:]))
|
|
||||||
return 0, scriptError(ErrMalformedPush, str)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Slice out the data.
|
|
||||||
pop.data = script[scriptPos+1 : scriptPos+pop.opcode.length]
|
|
||||||
scriptPos += pop.opcode.length
|
|
||||||
|
|
||||||
// Data pushes with parsed lengths -- OP_PUSHDATAP{1,2,4}.
|
|
||||||
case pop.opcode.length < 0:
|
|
||||||
var l uint
|
|
||||||
off := scriptPos + 1
|
|
||||||
|
|
||||||
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 0, scriptError(ErrMalformedPush, str)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next -length bytes are little endian length of data.
|
|
||||||
switch pop.opcode.length {
|
|
||||||
case -1:
|
|
||||||
l = uint(script[off])
|
|
||||||
case -2:
|
|
||||||
l = ((uint(script[off+1]) << 8) |
|
|
||||||
uint(script[off]))
|
|
||||||
case -4:
|
|
||||||
l = ((uint(script[off+3]) << 24) |
|
|
||||||
(uint(script[off+2]) << 16) |
|
|
||||||
(uint(script[off+1]) << 8) |
|
|
||||||
uint(script[off]))
|
|
||||||
default:
|
|
||||||
str := fmt.Sprintf("invalid opcode length %d",
|
|
||||||
pop.opcode.length)
|
|
||||||
return 0, scriptError(ErrMalformedPush, str)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move offset to beginning of the data.
|
|
||||||
off += -pop.opcode.length
|
|
||||||
|
|
||||||
// Disallow entries that do not fit script or were
|
|
||||||
// sign extended.
|
|
||||||
if int(l) > len(script[off:]) || int(l) < 0 {
|
|
||||||
str := fmt.Sprintf("opcode %s pushes %d bytes, "+
|
|
||||||
"but script only has %d remaining",
|
|
||||||
pop.opcode.name, int(l), len(script[off:]))
|
|
||||||
return 0, scriptError(ErrMalformedPush, str)
|
|
||||||
}
|
|
||||||
|
|
||||||
pop.data = script[off : off+int(l)]
|
|
||||||
scriptPos += 1 - pop.opcode.length + int(l)
|
|
||||||
}
|
|
||||||
return scriptPos, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// disasmOpcode writes a human-readable disassembly of the provided opcode and
|
// disasmOpcode writes a human-readable disassembly of the provided opcode and
|
||||||
// data into the provided buffer. The compact flag indicates the disassembly
|
// data into the provided buffer. The compact flag indicates the disassembly
|
||||||
// should print a more compact representation of data-carrying and small integer
|
// should print a more compact representation of data-carrying and small integer
|
||||||
|
|
|
@ -143,65 +143,6 @@ func IsPushOnlyScript(script []byte) bool {
|
||||||
return tokenizer.Err() == nil
|
return tokenizer.Err() == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseScriptTemplate is the same as parseScript but allows the passing of the
|
|
||||||
// template list for testing purposes. When there are parse errors, it returns
|
|
||||||
// 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}
|
|
||||||
i, err = pop.checkParseableInScript(script, i)
|
|
||||||
if err != nil {
|
|
||||||
return retScript, err
|
|
||||||
}
|
|
||||||
|
|
||||||
retScript = append(retScript, pop)
|
|
||||||
}
|
|
||||||
|
|
||||||
return retScript, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkScriptTemplateParseable is the same as parseScriptTemplate but does not
|
|
||||||
// return the list of opcodes up until the point of failure so that this can be
|
|
||||||
// used in functions which do not necessarily have a need for the failed list of
|
|
||||||
// opcodes, such as IsUnspendable.
|
|
||||||
//
|
|
||||||
// This function returns a pointer to a byte. This byte is nil if the parsing
|
|
||||||
// has an error, or if the script length is zero. If the script length is not
|
|
||||||
// zero and parsing succeeds, then the first opcode parsed will be returned.
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
|
|
||||||
for i := 0; i < len(script); {
|
|
||||||
instr := script[i]
|
|
||||||
op := &opcodes[instr]
|
|
||||||
pop := parsedOpcode{opcode: op}
|
|
||||||
i, err = pop.checkParseableInScript(script, i)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// if this is a op_return then it is unspendable so we set the first
|
|
||||||
// parsed instruction in case it's an op_return
|
|
||||||
if numParsedInstr == 0 {
|
|
||||||
firstOpcode = pop.opcode.value
|
|
||||||
}
|
|
||||||
numParsedInstr++
|
|
||||||
}
|
|
||||||
|
|
||||||
return &firstOpcode, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DisasmString formats a disassembled script for one line printing. When the
|
// DisasmString formats a disassembled script for one line printing. When the
|
||||||
// script fails to parse, the returned string will contain the disassembled
|
// script fails to parse, the returned string will contain the disassembled
|
||||||
// script up to the point the failure occurred along with the string '[error]'
|
// script up to the point the failure occurred along with the string '[error]'
|
||||||
|
|
|
@ -12,22 +12,6 @@ import (
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestParseOpcode tests for opcode parsing with bad data templates.
|
|
||||||
func TestParseOpcode(t *testing.T) {
|
|
||||||
// Deep copy the array and make one of the opcodes invalid by setting it
|
|
||||||
// to the wrong length.
|
|
||||||
fakeArray := opcodeArray
|
|
||||||
fakeArray[OP_PUSHDATA4] = opcode{value: OP_PUSHDATA4,
|
|
||||||
name: "OP_PUSHDATA4", length: -8, opfunc: opcodePushData}
|
|
||||||
|
|
||||||
// This script would be fine if -8 was a valid length.
|
|
||||||
_, err := parseScriptTemplate([]byte{OP_PUSHDATA4, 0x1, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}, &fakeArray)
|
|
||||||
if err == nil {
|
|
||||||
t.Errorf("no error with dodgy opcode array!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestPushedData ensured the PushedData function extracts the expected data out
|
// TestPushedData ensured the PushedData function extracts the expected data out
|
||||||
// of various scripts.
|
// of various scripts.
|
||||||
func TestPushedData(t *testing.T) {
|
func TestPushedData(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue