diff --git a/src/cjs/transaction.cjs b/src/cjs/transaction.cjs index 476023b2a..e4bed413d 100644 --- a/src/cjs/transaction.cjs +++ b/src/cjs/transaction.cjs @@ -107,7 +107,19 @@ class Transaction { marker === Transaction.ADVANCED_TRANSACTION_MARKER && flag === Transaction.ADVANCED_TRANSACTION_FLAG ) { - hasWitnesses = true; + const { bigintValue: vinLenPeek, bytes: vinLenBytes } = + bufferutils_js_1.varuint.decode(buffer, bufferReader.offset); + const minInputSize = 41; + const remainingAfterVinLen = + buffer.length - bufferReader.offset - vinLenBytes; + if ( + vinLenPeek === BigInt(0) || + Number(vinLenPeek) * minInputSize > remainingAfterVinLen + ) { + bufferReader.offset -= 2; + } else { + hasWitnesses = true; + } } else { bufferReader.offset -= 2; } diff --git a/src/esm/transaction.js b/src/esm/transaction.js index dfe233389..e5530b3d1 100644 --- a/src/esm/transaction.js +++ b/src/esm/transaction.js @@ -65,7 +65,21 @@ export class Transaction { marker === Transaction.ADVANCED_TRANSACTION_MARKER && flag === Transaction.ADVANCED_TRANSACTION_FLAG ) { - hasWitnesses = true; + const { bigintValue: vinLenPeek, bytes: vinLenBytes } = varuint.decode( + buffer, + bufferReader.offset, + ); + const minInputSize = 41; + const remainingAfterVinLen = + buffer.length - bufferReader.offset - vinLenBytes; + if ( + vinLenPeek === BigInt(0) || + Number(vinLenPeek) * minInputSize > remainingAfterVinLen + ) { + bufferReader.offset -= 2; + } else { + hasWitnesses = true; + } } else { bufferReader.offset -= 2; } diff --git a/ts_src/transaction.ts b/ts_src/transaction.ts index 8b943d713..bd72d47c3 100644 --- a/ts_src/transaction.ts +++ b/ts_src/transaction.ts @@ -77,23 +77,33 @@ export class Transaction { static fromBuffer(buffer: Uint8Array, _NO_STRICT?: boolean): Transaction { const bufferReader = new BufferReader(buffer); - const tx = new Transaction(); tx.version = bufferReader.readUInt32(); - const marker = bufferReader.readUInt8(); const flag = bufferReader.readUInt8(); - let hasWitnesses = false; if ( marker === Transaction.ADVANCED_TRANSACTION_MARKER && flag === Transaction.ADVANCED_TRANSACTION_FLAG ) { - hasWitnesses = true; + const { bigintValue: vinLenPeek, bytes: vinLenBytes } = varuint.decode( + buffer, + bufferReader.offset, + ); + const minInputSize = 41; + const remainingAfterVinLen = + buffer.length - bufferReader.offset - vinLenBytes; + if ( + vinLenPeek === BigInt(0) || + Number(vinLenPeek) * minInputSize > remainingAfterVinLen + ) { + bufferReader.offset -= 2; + } else { + hasWitnesses = true; + } } else { bufferReader.offset -= 2; } - const vinLen = bufferReader.readVarInt(); for (let i = 0; i < vinLen; ++i) { tx.ins.push({