Merge pull request #164 from Christewart/script_parse_bug

Fix overflow bug with parsing script with OP_PUSHDATA4
This commit is contained in:
Chris Stewart 2018-05-29 11:23:11 -04:00 committed by GitHub
commit 6cb62c1cc5
3 changed files with 13 additions and 3 deletions

View file

@ -93,6 +93,11 @@ class TransactionTest extends FlatSpec with MustMatchers {
}
it must "parse a transaction with an OP_PUSHDATA4 op code but not enough data to push" in {
val hex = "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff2a03f35c0507062f503253482ffe4ecb3b55fefbde06000963676d696e6572343208040000000000000000ffffffff0100f90295000000001976a91496621bc1c9d1e5a1293e401519365de820792bbc88ac00000000"
val btx = BaseTransaction.fromHex(hex)
btx.hex must be(hex)
}
it must "read all of the tx_valid.json's contents and return ScriptOk" in {
val source = Source.fromURL(getClass.getResource("/tx_valid.json"))

View file

@ -29,7 +29,7 @@ sealed abstract class TransactionSignatureSerializer {
/**
* Implements the signature serialization algorithim that Satoshi Nakamoto originally created
* and the new signature serialization algorithm as specified by BIP143
* and the new signature serialization algorithm as specified by BIP143
* [[https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki]]
* [[https://github.com/bitcoin/bitcoin/blob/f8528134fc188abc5c7175a19680206964a8fade/src/script/interpreter.cpp#L1113]]
*/

View file

@ -221,9 +221,14 @@ sealed abstract class ScriptParser extends Factory[List[ScriptToken]] {
//TODO: Review this more, see this transaction's scriptSig as an example: b30d3148927f620f5b1228ba941c211fdabdae75d0ba0b688a58accbf018f3cc
val bytesForPushOp = Try(uInt32Push.toInt).getOrElse(Int.MaxValue)
val bytesToPushOntoStack = ScriptConstant(scriptConstantHex)
val scriptConstantBytes = tail.slice(numBytes, bytesForPushOp + numBytes)
val endIndex = {
val idx = bytesForPushOp + numBytes
//for the case of an overflow. Just assume Int.MaxValue for slice operation which only takes a Int
if (idx >= 0) idx else Int.MaxValue
}
val scriptConstantBytes = tail.slice(numBytes, endIndex)
val scriptConstant = ScriptConstant(scriptConstantBytes)
val restOfBytes = tail.slice(bytesForPushOp + numBytes, tail.size)
val restOfBytes = tail.slice(endIndex, tail.size)
buildParsingHelper(op, bytesToPushOntoStack, scriptConstant, restOfBytes, accum)
}