partial bitcoin#23595: Add ParseHex<std::byte>() helper

excludes:
- facd1fb911abfc595a3484ee53397eff515d4c40
This commit is contained in:
Kittywhiskers Van Gogh 2024-02-23 18:16:48 +00:00 committed by pasta
parent e4091aa477
commit cf4522f845
No known key found for this signature in database
GPG Key ID: 52527BEDABE87984
4 changed files with 20 additions and 6 deletions

View File

@ -20,6 +20,8 @@ FUZZ_TARGET(hex)
{ {
const std::string random_hex_string(buffer.begin(), buffer.end()); const std::string random_hex_string(buffer.begin(), buffer.end());
const std::vector<unsigned char> data = ParseHex(random_hex_string); const std::vector<unsigned char> data = ParseHex(random_hex_string);
const std::vector<std::byte> bytes{ParseHex<std::byte>(random_hex_string)};
assert(AsBytes(Span{data}) == Span{bytes});
const std::string hex_data = HexStr(data); const std::string hex_data = HexStr(data);
if (IsHex(random_hex_string)) { if (IsHex(random_hex_string)) {
assert(ToLower(random_hex_string) == hex_data); assert(ToLower(random_hex_string) == hex_data);

View File

@ -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, 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d,
0x5f 0x5f
}; };
BOOST_AUTO_TEST_CASE(util_ParseHex) BOOST_AUTO_TEST_CASE(parse_hex)
{ {
std::vector<unsigned char> result; std::vector<unsigned char> result;
std::vector<unsigned char> expected(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected)); std::vector<unsigned char> expected(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected));
@ -165,6 +165,14 @@ BOOST_AUTO_TEST_CASE(util_ParseHex)
result = ParseHex(" 89 34 56 78"); result = ParseHex(" 89 34 56 78");
BOOST_CHECK(result.size() == 4 && result[0] == 0x89 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78); 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 // Stop parsing at invalid value
result = ParseHex("1234 invalid 1234"); result = ParseHex("1234 invalid 1234");
BOOST_CHECK(result.size() == 2 && result[0] == 0x12 && result[1] == 0x34); BOOST_CHECK(result.size() == 2 && result[0] == 0x12 && result[1] == 0x34);

View File

@ -75,10 +75,10 @@ bool IsHexNumber(std::string_view str)
return str.size() > 0; return str.size() > 0;
} }
std::vector<unsigned char> ParseHex(std::string_view str) template <typename Byte>
std::vector<Byte> ParseHex(std::string_view str)
{ {
// convert hex dump to vector std::vector<Byte> vch;
std::vector<unsigned char> vch;
auto it = str.begin(); auto it = str.begin();
while (it != str.end() && it + 1 != str.end()) { while (it != str.end() && it + 1 != str.end()) {
if (IsSpace(*it)) { if (IsSpace(*it)) {
@ -88,10 +88,12 @@ std::vector<unsigned char> ParseHex(std::string_view str)
auto c1 = HexDigit(*(it++)); auto c1 = HexDigit(*(it++));
auto c2 = HexDigit(*(it++)); auto c2 = HexDigit(*(it++));
if (c1 < 0 || c2 < 0) break; if (c1 < 0 || c2 < 0) break;
vch.push_back(uint8_t(c1 << 4) | c2); vch.push_back(Byte(c1 << 4) | Byte(c2));
} }
return vch; return vch;
} }
template std::vector<std::byte> ParseHex(std::string_view);
template std::vector<uint8_t> ParseHex(std::string_view);
void SplitHostPort(std::string in, uint16_t& portOut, std::string& hostOut) void SplitHostPort(std::string in, uint16_t& portOut, std::string& hostOut)
{ {

View File

@ -36,7 +36,9 @@ enum SafeChars
* @return A new string without unsafe chars * @return A new string without unsafe chars
*/ */
std::string SanitizeString(std::string_view str, int rule = SAFE_CHARS_DEFAULT); std::string SanitizeString(std::string_view str, int rule = SAFE_CHARS_DEFAULT);
std::vector<unsigned char> ParseHex(std::string_view str); /** Parse the hex string into bytes (uint8_t or std::byte). Ignores whitespace. */
template <typename Byte = uint8_t>
std::vector<Byte> ParseHex(std::string_view str);
signed char HexDigit(char c); signed char HexDigit(char c);
/* Returns true if each character in str is a hex character, and has an even /* Returns true if each character in str is a hex character, and has an even
* number of hex digits.*/ * number of hex digits.*/