diff --git a/lib/bcoin/script.js b/lib/bcoin/script.js index 79dff160..b5ab951e 100644 --- a/lib/bcoin/script.js +++ b/lib/bcoin/script.js @@ -965,8 +965,8 @@ Script.prototype.removeSeparators = function removeSeparators() { var i; for (i = 0; i < this.code.length; i++) { - // NOTE: We do not check for bad pushes here. Bad - // pushes may have been created by FindAndDelete(). + if (Script.isBadPush(this.code[i])) + break; if (this.code[i] !== opcodes.OP_CODESEPARATOR) code.push(this.code[i]); } @@ -1954,7 +1954,7 @@ Script.array = function(value) { Script.prototype.removeData = function removeData(data) { var total = 0; - var p, sig, raw, i, a, b; + var p, sig, raw, i, a, b, op, size; // We need to reserialize the // signature as a minimal push @@ -1991,16 +1991,46 @@ Script.prototype.removeData = function removeData(data) { // Compare on the byte level. raw = this.encode(); - // Note that this is _faster_ than Buffer#indexOf. - for (i = 0; i < raw.length; i++) { - if (raw.length - i < sig.length) - break; - if (utils.icmp(raw, sig, i) === 0) { - a = raw.slice(0, i); - b = raw.slice(i + sig.length); + p = new BufferReader(raw, true); + + while (p.left() >= sig.length) { + if (utils.icmp(raw, sig, p.offset) === 0) { + a = raw.slice(0, p.offset); + b = raw.slice(p.offset + sig.length); raw = Buffer.concat([a, b]); + p.data = raw; total++; } + + if (p.left() === 0) + break; + + op = p.readU8(); + if (op >= 0x01 && op <= 0x4b) { + if (p.left() < op) + break; + } else if (op === opcodes.OP_PUSHDATA1) { + if (p.left() < 1) + break; + size = p.readU8(); + if (p.left() < size) + break; + p.seek(size); + } else if (op === opcodes.OP_PUSHDATA2) { + if (p.left() < 2) + break; + size = p.readU16(); + if (p.left() < size) + break; + p.seek(size); + } else if (op === opcodes.OP_PUSHDATA4) { + if (p.left() < 4) + break; + size = p.readU32(); + if (p.left() < size) + break; + p.seek(size); + } } if (total > 0) { @@ -3374,16 +3404,13 @@ Script.format = function format(code) { var op, size; if (Buffer.isBuffer(chunk)) { - op = chunk.op; + op = chunk.opcode; if (op == null) { if (chunk.length === 0) { op = opcodes.OP_0; } else if (chunk.length <= 0x4b) { if (chunk.length === 1) { - if (chunk[0] === 0) { - op = opcodes.OP_0; - return constants.opcodesByVal[op]; - } else if (chunk[0] >= 1 && chunk[0] <= 16) { + if (chunk[0] >= 1 && chunk[0] <= 16) { op = chunk[0] + 0x50; return constants.opcodesByVal[op]; } else if (chunk[0] === 0x81) { diff --git a/lib/bcoin/tx.js b/lib/bcoin/tx.js index 64728a57..93bd6756 100644 --- a/lib/bcoin/tx.js +++ b/lib/bcoin/tx.js @@ -1513,6 +1513,8 @@ TX.prototype.isWatched = function isWatched(bloom) { for (i = 0; i < code.length; i++) { chunk = code[i]; + if (Script.isBadPush(chunk)) + break; if (!Buffer.isBuffer(chunk) || chunk.length === 0) continue; if (bloom.test(chunk)) diff --git a/scripts/gen.js b/scripts/gen.js index cd56966c..325fed5d 100644 --- a/scripts/gen.js +++ b/scripts/gen.js @@ -51,6 +51,8 @@ function createGenesisBlock(options) { locktime: 0 }; + tx.inputs[0].script.code[1].opcode = 1; + txRaw = bcoin.protocol.framer.tx(tx); tx._raw = txRaw; tx._size = txRaw.length; @@ -117,7 +119,7 @@ var segnet3 = createGenesisBlock({ var segnet4 = createGenesisBlock({ version: 1, ts: 1452831101, - bits: utils.toCompact(network.segnet4.powLimit), + bits: utils.toCompact(network.segnet4.pow.limit), nonce: 0 }); @@ -126,15 +128,15 @@ utils.print(testnet); utils.print(regtest); utils.print(segnet3); utils.print('main hash: %s', utils.revHex(main.hash)); -utils.print('main raw: %s', utils.toHex(main._raw)); +utils.print('main raw: %s', main._raw.toString('hex')); utils.print(''); utils.print('testnet hash: %s', utils.revHex(testnet.hash)); -utils.print('testnet raw: %s', utils.toHex(testnet._raw)); +utils.print('testnet raw: %s', testnet._raw.toString('hex')); utils.print(''); utils.print('regtest hash: %s', utils.revHex(regtest.hash)); -utils.print('regtest raw: %s', utils.toHex(regtest._raw)); +utils.print('regtest raw: %s', regtest._raw.toString('hex')); utils.print('segnet3 hash: %s', utils.revHex(segnet3.hash)); -utils.print('segnet3 raw: %s', utils.toHex(segnet3._raw)); +utils.print('segnet3 raw: %s', segnet3._raw.toString('hex')); utils.print('segnet4 hash: %s', utils.revHex(segnet4.hash)); -utils.print('segnet4 raw: %s', utils.toHex(segnet4._raw)); +utils.print('segnet4 raw: %s', segnet4._raw.toString('hex')); utils.print(segnet4);