diff --git a/bitcoin/block.c b/bitcoin/block.c index 6838f2c39344..076d443f8915 100644 --- a/bitcoin/block.c +++ b/bitcoin/block.c @@ -155,7 +155,7 @@ bitcoin_block_from_hex(const tal_t *ctx, const struct chainparams *chainparams, /* De-hex the array. */ len = hex_data_size(hexlen); - p = linear_tx = tal_arr(ctx, u8, len); + p = linear_tx = tal_arr(b, u8, len); if (!hex_decode(hex, hexlen, linear_tx, len)) return tal_free(b); @@ -210,6 +210,8 @@ bitcoin_block_from_hex(const tal_t *ctx, const struct chainparams *chainparams, b->txids = tal_arr(b, struct bitcoin_txid, num); for (i = 0; i < num; i++) { b->tx[i] = pull_bitcoin_tx_only(b->tx, &p, &len); + if (!b->tx[i]) + return tal_free(b); b->tx[i]->chainparams = chainparams; bitcoin_txid(b->tx[i], &b->txids[i]); } diff --git a/bitcoin/test/run-bitcoin_block_from_hex.c b/bitcoin/test/run-bitcoin_block_from_hex.c index 94b26ad5d05f..aa1bf7c99b23 100644 --- a/bitcoin/test/run-bitcoin_block_from_hex.c +++ b/bitcoin/test/run-bitcoin_block_from_hex.c @@ -68,6 +68,7 @@ int main(int argc, const char *argv[]) struct sha256_double merkle; struct bitcoin_txid txid, expected_txid; struct bitcoin_block *b; + size_t blocklen; common_setup(argv[0]); chainparams = chainparams_for_network("bitcoin"); @@ -103,6 +104,12 @@ int main(int argc, const char *argv[]) assert(bitcoin_txid_eq(&txid, &expected_txid)); tal_free(b); + + /* Every truncation of a valid block must be refused, not crash. */ + blocklen = strlen(block); + for (size_t i = 1; i < blocklen; i++) + assert(!bitcoin_block_from_hex(NULL, chainparams, block, i)); + common_shutdown(); return 0; }