diff --git a/src/lib/base/String.cpp b/src/lib/base/String.cpp index 413ad449..adbb11db 100644 --- a/src/lib/base/String.cpp +++ b/src/lib/base/String.cpp @@ -234,20 +234,27 @@ std::string to_hex(const std::vector& subject, int width, const ch std::vector from_hex(const std::string& data) { - if ((data.size() % 2) != 0) { - return {}; - } - std::vector result; result.reserve(data.size() / 2); - for (std::size_t i = 0; i < data.size(); i += 2) { + std::size_t i = 0; + while (i < data.size()) { + if (data[i] == ':') { + i++; + continue; + } + + if (i + 2 > data.size()) { + return {}; // uneven character count follows, it's unclear how to interpret it + } + auto high = hex_to_number(data[i]); auto low = hex_to_number(data[i + 1]); if (high < 0 || low < 0) { return {}; } result.push_back(high * 16 + low); + i += 2; } return result; } diff --git a/src/test/unittests/base/StringTests.cpp b/src/test/unittests/base/StringTests.cpp index ad5d5157..cc8e4fc6 100644 --- a/src/test/unittests/base/StringTests.cpp +++ b/src/test/unittests/base/StringTests.cpp @@ -69,6 +69,13 @@ TEST(StringTests, fromhex_plaintext_string) EXPECT_EQ(result, std::vector(expected.begin(), expected.end())); } +TEST(StringTests, fromhex_plaintext_string_colons) +{ + auto result = string::from_hex("66:6f:6f:62:61:72"); + std::string expected = "foobar"; + EXPECT_EQ(result, std::vector(expected.begin(), expected.end())); +} + TEST(StringTests, fromhex_binary_string) { auto result = string::from_hex("01020304050600fff9"); @@ -76,6 +83,13 @@ TEST(StringTests, fromhex_binary_string) EXPECT_EQ(result, expected); } +TEST(StringTests, fromhex_invalid_string) +{ + EXPECT_TRUE(string::from_hex("66:6").empty()); + EXPECT_TRUE(string::from_hex("66:612").empty()); + EXPECT_TRUE(string::from_hex("66:WW").empty()); +} + TEST(StringTests, uppercase_lowercaseInput_uppercaseOutput) { String subject = "12foo3BaR";