From 42f6576b02636de92e44e206421ca4d0c622996b Mon Sep 17 00:00:00 2001 From: "Owain G. Ainsworth" Date: Fri, 14 Mar 2014 18:40:35 +0000 Subject: [PATCH] Enforce max script length of 10000. Detected by bitcoind negative script tests. Note that this length is only for *executing* scripts, this is why it is in NewScript. --- script.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/script.go b/script.go index a3819b01..9fa4a68d 100644 --- a/script.go +++ b/script.go @@ -24,6 +24,10 @@ var ( // too long for the length of the script. StackErrShortScript = errors.New("execute past end of script") + // StackErrLongScript is returned if the script has an opcode that is + // too long for the length of the script. + StackErrLongScript = errors.New("script is longer than maximum allowed") + // StackErrUnderflow is returned if an opcode requires more items on the // stack than is present. StackErrUnderflow = errors.New("stack underflow") @@ -122,9 +126,14 @@ var ( StackErrOverflow = errors.New("Stacks overflowed") ) -// maxStackSize is the maximum combined height of stack and alt stack during -// execution. -const maxStackSize = 1000 +const ( + // maxStackSize is the maximum combined height of stack and alt stack + // during execution. + maxStackSize = 1000 + + // maxScriptSize is the maximum allowed length of a raw script. + maxScriptSize = 10000 +) // ErrUnsupportedAddress is returned when a concrete type that implements // a btcutil.Address is not a supported type. @@ -492,6 +501,9 @@ func NewScript(scriptSig []byte, scriptPubKey []byte, txidx int, tx *btcwire.Msg scripts := [][]byte{scriptSig, scriptPubKey} m.scripts = make([][]parsedOpcode, len(scripts)) for i, scr := range scripts { + if len(scr) > maxScriptSize { + return nil, StackErrLongScript + } var err error m.scripts[i], err = parseScript(scr) if err != nil {