From 91acf2a607a69ef26c46ab12091e31e7d1866ae4 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 20 Apr 2016 09:01:10 -0700 Subject: [PATCH] new script decoder. --- lib/bcoin/script.js | 116 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/lib/bcoin/script.js b/lib/bcoin/script.js index 0d334eeb..b533088e 100644 --- a/lib/bcoin/script.js +++ b/lib/bcoin/script.js @@ -12,6 +12,7 @@ var constants = bcoin.protocol.constants; var utils = require('./utils'); var assert = utils.assert; var BufferWriter = require('./writer'); +var BufferReader = require('./reader'); var opcodes = constants.opcodes; var STACK_TRUE = new Buffer([1]); var STACK_FALSE = new Buffer([]); @@ -2154,6 +2155,8 @@ Script.isCode = function isCode(buf) { op = code[i]; if (Buffer.isBuffer(op)) continue; + if (op >= opcodes.OP_PUSHDATA1 && op <= opcodes.OP_PUSHDATA4) + return false; if (constants.opcodesByVal[op] == null) return false; } @@ -2666,6 +2669,8 @@ Script.prototype.isNulldata = function isNulldata() { } if (op > opcodes.OP_16) return false; + if (op >= opcodes.OP_PUSHDATA1 && op <= opcodes.OP_PUSHDATA4) + return false; } return true; @@ -3487,6 +3492,8 @@ Script.prototype.isPushOnly = function isPushOnly() { } if (op > opcodes.OP_16) return false; + if (op >= opcodes.OP_PUSHDATA1 && op <= opcodes.OP_PUSHDATA4) + return false; } return true; }; @@ -3509,6 +3516,9 @@ Script.prototype.getSigops = function getSigops(accurate) { if (Script.isPush(op)) continue; + if (op >= opcodes.OP_PUSHDATA1 && op <= opcodes.OP_PUSHDATA4) + return 0; + if (constants.opcodesByVal[op] == null) return 0; @@ -4075,6 +4085,19 @@ Script.fromRaw = function fromRaw(data, enc) { * @returns {Array} Script code. */ +Script.isPushOp = function isPushOp(op) { + if (Buffer.isBuffer(op)) { + if (!Script.checkPush(op)) + return false; + return true; + } + if (op > opcodes.OP_16) + return false; + if (op >= opcodes.OP_PUSHDATA1 && op <= opcodes.OP_PUSHDATA4) + return false; + return true; +}; + Script.decode = function decode(buf) { var code = []; var off = 0; @@ -4130,6 +4153,99 @@ Script.decode = function decode(buf) { return code; }; +Script.decode = function decode(buf) { + var code = []; + var p = new BufferReader(buf, true); + var off = 0; + var op, size; + + assert(Buffer.isBuffer(buf)); + + while (p.left()) { + op = p.readU8(); + if (op >= 0x01 && op <= 0x4b) { + data = p.readBytes(Math.min(p.left(), op)); + utils.hidden(data, 'pushdata', { + opcode: null, + size: op + }); + code.push(data); + } else if (op === opcodes.OP_PUSHDATA1) { + if (p.left() < 1) { + code.push(op); + while (p.left()) + code.push(p.readU8()); + continue; + } + size = p.readU8(); + if (p.left() < size) { + code.push(op); + code.push(size); + while (p.left()) + code.push(p.readU8()); + continue; + } + data = p.readBytes(Math.min(p.left(), size)); + utils.hidden(data, 'pushdata', { + opcode: op, + size: size + }); + code.push(data); + } else if (op === opcodes.OP_PUSHDATA2) { + if (p.left() < 2) { + code.push(op); + while (p.left()) + code.push(p.readU8()); + continue; + } + size = p.readU16(); + if (p.left() < size) { + code.push(op); + code.push(size & 0xff); + code.push((size >>> 8) & 0xff); + while (p.left()) + code.push(p.readU8()); + continue; + } + data = p.readBytes(Math.min(p.left(), size)); + utils.hidden(data, 'pushdata', { + opcode: op, + size: size + }); + code.push(data); + } else if (op === opcodes.OP_PUSHDATA4) { + if (p.left() < 4) { + code.push(op); + while (p.left()) + code.push(p.readU8()); + continue; + } + size = p.readU32(); + if (p.left() < size) { + code.push(op); + code.push(size & 0xff); + code.push((size >>> 8) & 0xff); + code.push((size >>> 16) & 0xff); + code.push((size >>> 24) & 0xff); + while (p.left()) + code.push(p.readU8()); + continue; + } + data = p.readBytes(Math.min(p.left(), size)); + utils.hidden(data, 'pushdata', { + opcode: op, + size: size + }); + code.push(data); + } else { + code.push(op); + } + } + + return code; +}; + + /** * Encode and serialize script code. This will _not_ * include the varint size at the start. This will