Skip to content

Commit 051faf7

Browse files
committed
add a test demonstrating an overflow in a deserialization edge case
Also add a test that the highest legal index is accepted.
1 parent d26d15c commit 051faf7

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

src/test/blockencodings_tests.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,4 +344,49 @@ BOOST_AUTO_TEST_CASE(TransactionsRequestSerializationTest) {
344344
BOOST_CHECK_EQUAL(req1.indexes[3], req2.indexes[3]);
345345
}
346346

347+
BOOST_AUTO_TEST_CASE(TransactionsRequestDeserializationMaxTest) {
348+
// Check that the highest legal index is decoded correctly
349+
BlockTransactionsRequest req0;
350+
req0.blockhash = InsecureRand256();
351+
req0.indexes.resize(1);
352+
req0.indexes[0] = 0xffff;
353+
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
354+
stream << req0;
355+
356+
BlockTransactionsRequest req1;
357+
stream >> req1;
358+
BOOST_CHECK_EQUAL(req0.indexes.size(), req1.indexes.size());
359+
BOOST_CHECK_EQUAL(req0.indexes[0], req1.indexes[0]);
360+
}
361+
362+
BOOST_AUTO_TEST_CASE(TransactionsRequestDeserializationOverflowTest) {
363+
// Any set of index deltas that starts with N values that sum to (0x10000 - N)
364+
// causes the edge-case overflow that was originally not checked for. Such
365+
// a request cannot be created by serializing a real BlockTransactionsRequest
366+
// due to the overflow, so here we'll serialize from raw deltas.
367+
BlockTransactionsRequest req0;
368+
req0.blockhash = InsecureRand256();
369+
req0.indexes.resize(3);
370+
req0.indexes[0] = 0x7000;
371+
req0.indexes[1] = 0x10000 - 0x7000 - 2;
372+
req0.indexes[2] = 0;
373+
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
374+
stream << req0.blockhash;
375+
WriteCompactSize(stream, req0.indexes.size());
376+
WriteCompactSize(stream, req0.indexes[0]);
377+
WriteCompactSize(stream, req0.indexes[1]);
378+
WriteCompactSize(stream, req0.indexes[2]);
379+
380+
BlockTransactionsRequest req1;
381+
try {
382+
stream >> req1;
383+
// before patch: deserialize above succeeds and this check fails, demonstrating the overflow
384+
BOOST_CHECK(req1.indexes[1] < req1.indexes[2]);
385+
// this shouldn't be reachable before or after patch
386+
BOOST_CHECK(0);
387+
} catch(std::ios_base::failure &) {
388+
// deserialize should fail
389+
}
390+
}
391+
347392
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)