From f89dcda0a23fda74a6b98315b43ae4876bee0db1 Mon Sep 17 00:00:00 2001 From: "Ryan X. Charles" Date: Mon, 24 Mar 2014 20:18:08 -0400 Subject: [PATCH 1/2] script parsing should be more loose on pushdata This testnet transaction was being parsed incorrectly: cc64de74ba7002bbf4e3646824d7bbf0920004fb2ce45aa7270c4116ff11b715 Script was throwing an error when it should not have been. The error was that PUSHDATA1 was trying to push 117 bytes to the stack, but it was followed by only 75 bytes. But this transaction is accepted as valid by bitcoin-qt on testnet. So we are mistaken by throwing an error in this case. --- Script.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/Script.js b/Script.js index ae4e479..ada391d 100644 --- a/Script.js +++ b/Script.js @@ -58,17 +58,14 @@ Script.prototype.parse = function() { } else if (opcode === OP_PUSHDATA1) { len = parser.word8(); chunk = parser.buffer(len); - if (chunk.length < len) throw new Error('Invalid data size: not enough data'); this.chunks.push(chunk); } else if (opcode === OP_PUSHDATA2) { len = parser.word16le(); chunk = parser.buffer(len); - if (chunk.length < len) throw new Error('Invalid data size: not enough data'); this.chunks.push(chunk); } else if (opcode === OP_PUSHDATA4) { len = parser.word32le(); chunk = parser.buffer(len); - if (chunk.length < len) throw new Error('Invalid data size: not enough data'); this.chunks.push(chunk); } else { this.chunks.push(opcode); From 4319a20676f11278b969d3dc758d1c2156043ad0 Mon Sep 17 00:00:00 2001 From: "Ryan X. Charles" Date: Mon, 24 Mar 2014 20:27:51 -0400 Subject: [PATCH 2/2] add test of correct parsing of valid script Even of OP_PUSHDATA1 says to push 117 bytes, if there are only 75 bytes following, this should still be pushed to the stack. --- test/test.Script.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/test.Script.js b/test/test.Script.js index 1b9e2fb..205192f 100644 --- a/test/test.Script.js +++ b/test/test.Script.js @@ -84,6 +84,15 @@ describe('Script', function() { }); }); + describe('#parse', function() { + it('should parse this valid script', function() { + var scriptHex = '6a0843435000010001004c75726c3d687474702533612532662532666c6f63616c686f7374253361343636313125326663253266324d794a6e5065774c5a6241596a6843666f695652526679733937746d5231516d4b61'; + var script = new Script(new Buffer(scriptHex, 'hex')); + should.exist(script); + script.chunks[2].length.should.equal(75); + }); + }); + testdata.dataScriptAll.forEach(function(datum) { if (datum.length < 2) throw new Error('Invalid test data'); var human = datum[0] + ' ' + datum[1];