From cf4522f845640f84a6ed611c344d6e0dafa5b2fe Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Fri, 23 Feb 2024 18:16:48 +0000 Subject: [PATCH] partial bitcoin#23595: Add ParseHex() helper excludes: - facd1fb911abfc595a3484ee53397eff515d4c40 --- src/test/fuzz/hex.cpp | 2 ++ src/test/util_tests.cpp | 10 +++++++++- src/util/strencodings.cpp | 10 ++++++---- src/util/strencodings.h | 4 +++- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/test/fuzz/hex.cpp b/src/test/fuzz/hex.cpp index 5917fbb96d..99ce4da764 100644 --- a/src/test/fuzz/hex.cpp +++ b/src/test/fuzz/hex.cpp @@ -20,6 +20,8 @@ FUZZ_TARGET(hex) { const std::string random_hex_string(buffer.begin(), buffer.end()); const std::vector data = ParseHex(random_hex_string); + const std::vector bytes{ParseHex(random_hex_string)}; + assert(AsBytes(Span{data}) == Span{bytes}); const std::string hex_data = HexStr(data); if (IsHex(random_hex_string)) { assert(ToLower(random_hex_string) == hex_data); diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index d741c1bc25..a0f743a6e7 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -149,7 +149,7 @@ static const unsigned char ParseHex_expected[65] = { 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 0x5f }; -BOOST_AUTO_TEST_CASE(util_ParseHex) +BOOST_AUTO_TEST_CASE(parse_hex) { std::vector result; std::vector expected(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected)); @@ -165,6 +165,14 @@ BOOST_AUTO_TEST_CASE(util_ParseHex) result = ParseHex(" 89 34 56 78"); BOOST_CHECK(result.size() == 4 && result[0] == 0x89 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78); + // Embedded null is treated as end + const std::string with_embedded_null{" 11 "s + " \0 " + " 22 "s}; + BOOST_CHECK_EQUAL(with_embedded_null.size(), 11); + result = ParseHex(with_embedded_null); + BOOST_CHECK(result.size() == 1 && result[0] == 0x11); + // Stop parsing at invalid value result = ParseHex("1234 invalid 1234"); BOOST_CHECK(result.size() == 2 && result[0] == 0x12 && result[1] == 0x34); diff --git a/src/util/strencodings.cpp b/src/util/strencodings.cpp index 08ea6910a5..4fb69b95ea 100644 --- a/src/util/strencodings.cpp +++ b/src/util/strencodings.cpp @@ -75,10 +75,10 @@ bool IsHexNumber(std::string_view str) return str.size() > 0; } -std::vector ParseHex(std::string_view str) +template +std::vector ParseHex(std::string_view str) { - // convert hex dump to vector - std::vector vch; + std::vector vch; auto it = str.begin(); while (it != str.end() && it + 1 != str.end()) { if (IsSpace(*it)) { @@ -88,10 +88,12 @@ std::vector ParseHex(std::string_view str) auto c1 = HexDigit(*(it++)); auto c2 = HexDigit(*(it++)); if (c1 < 0 || c2 < 0) break; - vch.push_back(uint8_t(c1 << 4) | c2); + vch.push_back(Byte(c1 << 4) | Byte(c2)); } return vch; } +template std::vector ParseHex(std::string_view); +template std::vector ParseHex(std::string_view); void SplitHostPort(std::string in, uint16_t& portOut, std::string& hostOut) { diff --git a/src/util/strencodings.h b/src/util/strencodings.h index 543cc4ef00..9cb5b30df9 100644 --- a/src/util/strencodings.h +++ b/src/util/strencodings.h @@ -36,7 +36,9 @@ enum SafeChars * @return A new string without unsafe chars */ std::string SanitizeString(std::string_view str, int rule = SAFE_CHARS_DEFAULT); -std::vector ParseHex(std::string_view str); +/** Parse the hex string into bytes (uint8_t or std::byte). Ignores whitespace. */ +template +std::vector ParseHex(std::string_view str); signed char HexDigit(char c); /* Returns true if each character in str is a hex character, and has an even * number of hex digits.*/