Merge bitcoin/bitcoin#30482: rest: Reject truncated hex txid early in getutxos parsing

fac0c3d4bf doc: Add release notes for two pull requests (MarcoFalke)
fa7b57e5f5 refactor: Replace ParseHashStr with FromHex (MarcoFalke)
fa90777245 rest: Reject truncated hex txid early in getutxos parsing (MarcoFalke)
fab6ddbee6 refactor: Expose FromHex in transaction_identifier (MarcoFalke)
fad2991ba0 refactor: Implement strict uint256::FromHex() (MarcoFalke)
fa103db2bb scripted-diff: Rename SetHex to SetHexDeprecated (MarcoFalke)
fafe4b8051 test: refactor: Replace SetHex with uint256 constructor directly (MarcoFalke)

Pull request description:

  In `rest_getutxos` truncated txids such as `aa` or `ff` are accepted. This is brittle at best.

  Fix it by rejecting any truncated (or overlarge) input.

  ----

  Review note: This also starts a major refactor to rework hex parsing in Bitcoin Core, meaning that a few refactor commits are included as well. They are explained individually in the commit message and the work will be continued in the future.

ACKs for top commit:
  stickies-v:
    re-ACK fac0c3d4bf - only doc and test updates to address review comments, thanks!
  hodlinator:
    ACK fac0c3d4bf

Tree-SHA512: 473feb3fcf6118443435d1dd321006135b0b54689bfbbcb1697bb5811a449bef51f475c715de6911ff3c4ea3bdb75f601861ff93347bc4414d6b9e5298105dd7
This commit is contained in:
merge-script
2024-07-25 13:49:21 +01:00
16 changed files with 98 additions and 82 deletions

View File

@@ -149,8 +149,7 @@ BOOST_AUTO_TEST_CASE(blockfilters_json_test)
unsigned int pos = 0;
/*int block_height =*/ test[pos++].getInt<int>();
uint256 block_hash;
BOOST_CHECK(ParseHashStr(test[pos++].get_str(), block_hash));
BOOST_CHECK(uint256::FromHex(test[pos++].get_str()));
CBlock block;
BOOST_REQUIRE(DecodeHexBlk(block, test[pos++].get_str()));
@@ -165,11 +164,9 @@ BOOST_AUTO_TEST_CASE(blockfilters_json_test)
tx_undo.vprevout.emplace_back(txout, 0, false);
}
uint256 prev_filter_header_basic;
BOOST_CHECK(ParseHashStr(test[pos++].get_str(), prev_filter_header_basic));
uint256 prev_filter_header_basic{*Assert(uint256::FromHex(test[pos++].get_str()))};
std::vector<unsigned char> filter_basic = ParseHex(test[pos++].get_str());
uint256 filter_header_basic;
BOOST_CHECK(ParseHashStr(test[pos++].get_str(), filter_header_basic));
uint256 filter_header_basic{*Assert(uint256::FromHex(test[pos++].get_str()))};
BlockFilter computed_filter_basic(BlockFilterType::BASIC, block, block_undo);
BOOST_CHECK(computed_filter_basic.GetFilter().GetEncoded() == filter_basic);

View File

@@ -27,8 +27,7 @@ FUZZ_TARGET(hex)
assert(ToLower(random_hex_string) == hex_data);
}
(void)IsHexNumber(random_hex_string);
uint256 result;
(void)ParseHashStr(random_hex_string, result);
(void)uint256::FromHex(random_hex_string);
(void)uint256S(random_hex_string);
try {
(void)HexToPubKey(random_hex_string);

View File

@@ -86,7 +86,7 @@ BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_negative_target)
uint256 hash;
unsigned int nBits;
nBits = UintToArith256(consensus.powLimit).GetCompact(true);
hash.SetHex("0x1");
hash = uint256{1};
BOOST_CHECK(!CheckProofOfWork(hash, nBits, consensus));
}
@@ -95,7 +95,7 @@ BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_overflow_target)
const auto consensus = CreateChainParams(*m_node.args, ChainType::MAIN)->GetConsensus();
uint256 hash;
unsigned int nBits{~0x00800000U};
hash.SetHex("0x1");
hash = uint256{1};
BOOST_CHECK(!CheckProofOfWork(hash, nBits, consensus));
}
@@ -107,7 +107,7 @@ BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_too_easy_target)
arith_uint256 nBits_arith = UintToArith256(consensus.powLimit);
nBits_arith *= 2;
nBits = nBits_arith.GetCompact();
hash.SetHex("0x1");
hash = uint256{1};
BOOST_CHECK(!CheckProofOfWork(hash, nBits, consensus));
}

View File

@@ -62,7 +62,7 @@ static std::string ArrayToString(const unsigned char A[], unsigned int width)
inline uint160 uint160S(std::string_view str)
{
uint160 rv;
rv.SetHex(str);
rv.SetHexDeprecated(str);
return rv;
}
@@ -157,7 +157,7 @@ BOOST_AUTO_TEST_CASE( comparison ) // <= >= < >
uint256S("1000000000000000000000000000000000000000000000000000000000000002"));
}
BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 GetSerializeSize, Serialize, Unserialize
BOOST_AUTO_TEST_CASE(methods) // GetHex SetHexDeprecated FromHex begin() end() size() GetLow64 GetSerializeSize, Serialize, Unserialize
{
BOOST_CHECK_EQUAL(R1L.GetHex(), R1L.ToString());
BOOST_CHECK_EQUAL(R2L.GetHex(), R2L.ToString());
@@ -166,12 +166,12 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G
uint256 TmpL(R1L);
BOOST_CHECK_EQUAL(TmpL, R1L);
// Verify previous values don't persist when setting to truncated string.
TmpL.SetHex("21");
TmpL.SetHexDeprecated("21");
BOOST_CHECK_EQUAL(TmpL.ToString(), "0000000000000000000000000000000000000000000000000000000000000021");
TmpL.SetHex(R2L.ToString()); BOOST_CHECK_EQUAL(TmpL, R2L);
TmpL.SetHex(ZeroL.ToString()); BOOST_CHECK_EQUAL(TmpL, uint256());
BOOST_CHECK_EQUAL(uint256::FromHex(R2L.ToString()).value(), R2L);
BOOST_CHECK_EQUAL(uint256::FromHex(ZeroL.ToString()).value(), uint256());
TmpL.SetHex(R1L.ToString());
TmpL = uint256::FromHex(R1L.ToString()).value();
BOOST_CHECK_EQUAL_COLLECTIONS(R1L.begin(), R1L.end(), R1Array, R1Array + R1L.size());
BOOST_CHECK_EQUAL_COLLECTIONS(TmpL.begin(), TmpL.end(), R1Array, R1Array + TmpL.size());
BOOST_CHECK_EQUAL_COLLECTIONS(R2L.begin(), R2L.end(), R2Array, R2Array + R2L.size());
@@ -214,10 +214,10 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G
BOOST_CHECK_EQUAL(MaxS.GetHex(), MaxS.ToString());
uint160 TmpS(R1S);
BOOST_CHECK_EQUAL(TmpS, R1S);
TmpS.SetHex(R2S.ToString()); BOOST_CHECK_EQUAL(TmpS, R2S);
TmpS.SetHex(ZeroS.ToString()); BOOST_CHECK_EQUAL(TmpS, uint160());
BOOST_CHECK_EQUAL(uint160::FromHex(R2S.ToString()).value(), R2S);
BOOST_CHECK_EQUAL(uint160::FromHex(ZeroS.ToString()).value(), uint160());
TmpS.SetHex(R1S.ToString());
TmpS = uint160::FromHex(R1S.ToString()).value();
BOOST_CHECK_EQUAL_COLLECTIONS(R1S.begin(), R1S.end(), R1Array, R1Array + R1S.size());
BOOST_CHECK_EQUAL_COLLECTIONS(TmpS.begin(), TmpS.end(), R1Array, R1Array + TmpS.size());
BOOST_CHECK_EQUAL_COLLECTIONS(R2S.begin(), R2S.end(), R2Array, R2Array + R2S.size());