diff --git a/src/util/strencodings.h b/src/util/strencodings.h --- a/src/util/strencodings.h +++ b/src/util/strencodings.h @@ -52,7 +52,7 @@ /** * Return true if the string is a hex number, optionally prefixed with "0x" */ -bool IsHexNumber(const std::string &str); +bool IsHexNumber(const std::string &str) noexcept; std::vector DecodeBase64(const char *p, bool *pfInvalid = nullptr); std::string DecodeBase64(const std::string &str); std::string EncodeBase64(const uint8_t *pch, size_t len); diff --git a/src/util/strencodings.cpp b/src/util/strencodings.cpp --- a/src/util/strencodings.cpp +++ b/src/util/strencodings.cpp @@ -67,18 +67,22 @@ return (str.size() > 0) && (str.size() % 2 == 0); } -bool IsHexNumber(const std::string &str) { +bool IsHexNumber(const std::string &string) noexcept { size_t starting_location = 0; - if (str.size() > 2 && *str.begin() == '0' && *(str.begin() + 1) == 'x') { - starting_location = 2; - } - for (auto c : str.substr(starting_location)) { - if (HexDigit(c) < 0) { - return false; + try { + if (string.substr(0, 2) == "0x") { + starting_location = 2; } + } catch (const std::out_of_range &oor) { + } // substr(0,x) should never throw out_of_range, but hey, compilers + + // if string is just "" or "0x", return false + if (string.size() == starting_location) { + return false; } - // Return false for empty string or "0x". - return (str.size() > starting_location); + + return string.find_first_not_of("0123456789abcdefABCDEF", + starting_location) == std::string::npos; } std::vector ParseHex(const char *psz) {