From 03d200bad76a03ac5423093062272c35dcd7a23c Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Tue, 18 Mar 2014 18:46:19 -0300 Subject: [PATCH] some invalid script tests working --- Script.js | 22 +++++++---- ScriptInterpreter.js | 2 +- test/test.ScriptInterpreter.js | 71 ++++++++++++++++++++++++---------- test/test.examples.js | 4 +- 4 files changed, 68 insertions(+), 31 deletions(-) diff --git a/Script.js b/Script.js index d0abe3a..2ef22c4 100644 --- a/Script.js +++ b/Script.js @@ -33,8 +33,10 @@ function Script(buffer) { } else { this.buffer = util.EMPTY_BUFFER; } + console.log(buffertools.toHex(this.buffer)); this.chunks = []; this.parse(); + console.log(this.chunks); }; this.class = Script; @@ -51,19 +53,25 @@ Script.prototype.parse = function() { while (!parser.eof()) { var opcode = parser.word8(); - var len; + var len, chunk; if (opcode > 0 && opcode < OP_PUSHDATA1) { // Read some bytes of data, opcode value is the length of data this.chunks.push(parser.buffer(opcode)); - } else if (opcode == OP_PUSHDATA1) { + } else if (opcode === OP_PUSHDATA1) { len = parser.word8(); - this.chunks.push(parser.buffer(len)); - } else if (opcode == OP_PUSHDATA2) { + 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(); - this.chunks.push(parser.buffer(len)); - } else if (opcode == OP_PUSHDATA4) { + 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(); - this.chunks.push(parser.buffer(len)); + 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); } diff --git a/ScriptInterpreter.js b/ScriptInterpreter.js index 39a240d..0f5210f 100644 --- a/ScriptInterpreter.js +++ b/ScriptInterpreter.js @@ -30,7 +30,7 @@ ScriptInterpreter.prototype.eval = function eval(script, tx, inIndex, hashType, if ("function" !== typeof callback) { throw new Error("ScriptInterpreter.eval() requires a callback"); } - + var pc = 0; var execStack = []; var altStack = []; diff --git a/test/test.ScriptInterpreter.js b/test/test.ScriptInterpreter.js index dbdbae6..f245fcf 100644 --- a/test/test.ScriptInterpreter.js +++ b/test/test.ScriptInterpreter.js @@ -23,42 +23,71 @@ describe('ScriptInterpreter', function() { var si = new ScriptInterpreter(); should.exist(si); }); - testdata.dataScriptValid.forEach(function(datum) { - if (datum.length < 2) throw new Error('Invalid test data'); - var scriptSig = datum[0]; // script inputs - var scriptPubKey = datum[1]; // output script - var human = scriptSig + ' ' + scriptPubKey; - it('should validate script ' + human, function(done) { - ScriptInterpreter.verify(Script.fromHumanReadable(scriptSig), - Script.fromHumanReadable(scriptPubKey), - null, 0, 0, // tx, output index, and hashtype - function(err, result) { - should.not.exist(err); - result.should.equal(true); + var testScripts = function(data, valid) { + var i = 0; + data.forEach(function(datum) { + if (datum.length < 2) throw new Error('Invalid test data'); + var scriptSig = datum[0]; // script inputs + var scriptPubKey = datum[1]; // output script + var human = scriptSig + ' ' + scriptPubKey; + it('should ' + (!valid ? 'not ' : '') + 'validate script ' + human, function(done) { + console.log((!valid ? 'invalid ' : 'valid ') + human + ';' + (i++) + ' - ' + datum[2]); + try { + ScriptInterpreter.verify( + Script.fromHumanReadable(scriptSig), + Script.fromHumanReadable(scriptPubKey), + null, 0, 0, // tx, output index, and hashtype + function(err, result) { + if (valid) { + should.not.exist(err); + } else { + var failed = (typeof err !== 'undefined') || (result === false); + console.log('err=' + err); + console.log('result=' + result); + failed.should.equal(true); + } + if (typeof result !== 'undefined') { + result.should.equal(valid); + } + done(); + } + ); + } catch (e) { + if (valid) { + console.log(e); + } + valid.should.equal(false); done(); } - ); + + }); }); - }); + }; + testScripts(testdata.dataScriptValid, true); + testScripts(testdata.dataScriptInvalid, false); + + + testdata.dataSigCanonical.forEach(function(datum) { it('should validate valid canonical signatures', function() { - ScriptInterpreter.isCanonicalSignature(new Buffer(datum,'hex')).should.equal(true); + ScriptInterpreter.isCanonicalSignature(new Buffer(datum, 'hex')).should.equal(true); }); }); - testdata.dataSigNonCanonical.forEach(function(datum) { + testdata.dataSigNonCanonical.forEach(function(datum) { it('should NOT validate invalid canonical signatures', function() { var sig; var isHex; //is Hex? try { - sig =new Buffer(datum,'hex'); - isHex=1; - } catch (e) { } + sig = new Buffer(datum, 'hex'); + isHex = 1; + } catch (e) {} if (isHex) - ScriptInterpreter.isCanonicalSignature.bind(sig).should.throw(); + ScriptInterpreter.isCanonicalSignature.bind(sig).should. + throw (); }); }); - + }); diff --git a/test/test.examples.js b/test/test.examples.js index 4115bc7..55c9ccd 100644 --- a/test/test.examples.js +++ b/test/test.examples.js @@ -15,8 +15,8 @@ var examples = [ ]; describe('Examples', function() { - before(mute); - after(unmute); + //before(mute); + //after(unmute); examples.forEach(function(example) { it('valid '+example, function() { var ex = require('../examples/'+example);