From f6187cd8111e5f7e812d7a153f8cd64ac2c04cb9 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Wed, 14 Nov 2018 21:56:32 +0000 Subject: [PATCH 1/3] epee: speed up parse_hexstr_to_binbuff a little --- contrib/epee/include/string_tools.h | 50 ++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/contrib/epee/include/string_tools.h b/contrib/epee/include/string_tools.h index aba065cc7..6a063cc36 100644 --- a/contrib/epee/include/string_tools.h +++ b/contrib/epee/include/string_tools.h @@ -59,6 +59,26 @@ #pragma comment (lib, "Rpcrt4.lib") #endif +static const constexpr unsigned char isx[256] = +{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; + namespace epee { namespace string_tools @@ -98,30 +118,30 @@ namespace string_tools } //---------------------------------------------------------------------------- template - bool parse_hexstr_to_binbuff(const std::basic_string& s, std::basic_string& res, bool allow_partial_byte = false) + bool parse_hexstr_to_binbuff(const std::basic_string& s, std::basic_string& res) { res.clear(); - if (!allow_partial_byte && (s.size() & 1)) + if (s.size() & 1) return false; try { - long v = 0; - for(size_t i = 0; i < (s.size() + 1) / 2; i++) + res.resize(s.size() / 2); + unsigned char *dst = (unsigned char *)res.data(); + const unsigned char *src = (const unsigned char *)s.data(); + for(size_t i = 0; i < s.size(); i += 2) { - CharT byte_str[3]; - size_t copied = s.copy(byte_str, 2, 2 * i); - byte_str[copied] = CharT(0); - CharT* endptr; - v = strtoul(byte_str, &endptr, 16); - if (v < 0 || 0xFF < v || endptr != byte_str + copied) - { - return false; - } - res.push_back(static_cast(v)); + int tmp = *src++; + tmp = isx[tmp]; + if (tmp == 0xff) return false; + int t2 = *src++; + t2 = isx[t2]; + if (t2 == 0xff) return false; + *dst++ = (tmp << 4) | t2; } return true; - }catch(...) + } + catch(...) { return false; } From 6671110ca3db97f1169dd853fbb22ad725708e4a Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Thu, 15 Nov 2018 12:40:55 +0000 Subject: [PATCH 2/3] unit_tests: add a test for parse_hexstr_to_binbuff --- tests/unit_tests/epee_utils.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/unit_tests/epee_utils.cpp b/tests/unit_tests/epee_utils.cpp index c2b0b7647..b3c812dca 100644 --- a/tests/unit_tests/epee_utils.cpp +++ b/tests/unit_tests/epee_utils.cpp @@ -456,6 +456,19 @@ TEST(StringTools, PodToHex) ); } +TEST(StringTools, ParseHex) +{ + static const char data[] = "a10b68c2"; + for (size_t i = 0; i < sizeof(data); i += 2) + { + std::string res; + ASSERT_TRUE(epee::string_tools::parse_hexstr_to_binbuff(std::string(data, i), res)); + std::string hex = epee::string_tools::buff_to_hex_nodelimer(res); + ASSERT_EQ(hex.size(), i); + ASSERT_EQ(memcmp(data, hex.data(), i), 0); + } +} + TEST(StringTools, GetIpString) { EXPECT_EQ( From b36353e2681825474a9ddc6a6ccfe6098995a9f5 Mon Sep 17 00:00:00 2001 From: xiphon Date: Thu, 15 Nov 2018 23:32:42 +0000 Subject: [PATCH 3/3] unit_tests: add some hex parsing test for non hex input --- tests/unit_tests/epee_utils.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/unit_tests/epee_utils.cpp b/tests/unit_tests/epee_utils.cpp index b3c812dca..c384ce9a5 100644 --- a/tests/unit_tests/epee_utils.cpp +++ b/tests/unit_tests/epee_utils.cpp @@ -469,6 +469,22 @@ TEST(StringTools, ParseHex) } } +TEST(StringTools, ParseNotHex) +{ + std::string res; + for (size_t i = 0; i < 256; ++i) + { + std::string inputHexString = std::string(2, static_cast(i)); + if ((i >= '0' && i <= '9') || (i >= 'A' && i <= 'F') || (i >= 'a' && i <= 'f')) { + ASSERT_TRUE(epee::string_tools::parse_hexstr_to_binbuff(inputHexString, res)); + } else { + ASSERT_FALSE(epee::string_tools::parse_hexstr_to_binbuff(inputHexString, res)); + } + } + + ASSERT_FALSE(epee::string_tools::parse_hexstr_to_binbuff(std::string("a"), res)); +} + TEST(StringTools, GetIpString) { EXPECT_EQ(