diff --git a/src/governance/validators.cpp b/src/governance/validators.cpp index 13c3ffc9eb..af89b6adc4 100644 --- a/src/governance/validators.cpp +++ b/src/governance/validators.cpp @@ -100,7 +100,7 @@ bool CProposalValidator::ValidateName() static constexpr std::string_view strAllowedChars{"-_abcdefghijklmnopqrstuvwxyz0123456789"}; - std::transform(strName.begin(), strName.end(), strName.begin(), ToLower); + strName = ToLower(strName); if (strName.find_first_not_of(strAllowedChars) != std::string::npos) { strErrorMessages += "name contains invalid characters;"; diff --git a/src/netbase.cpp b/src/netbase.cpp index 83e128f606..680c3ac2a9 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -42,8 +42,8 @@ bool fNameLookup = DEFAULT_NAME_LOOKUP; static const int SOCKS5_RECV_TIMEOUT = 20 * 1000; static std::atomic interruptSocks5Recv(false); -enum Network ParseNetwork(std::string net) { - Downcase(net); +enum Network ParseNetwork(const std::string& net_in) { + std::string net = ToLower(net_in); if (net == "ipv4") return NET_IPV4; if (net == "ipv6") return NET_IPV6; if (net == "onion") return NET_ONION; diff --git a/src/netbase.h b/src/netbase.h index 7dc0992822..fa57b5914c 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -38,7 +38,7 @@ public: bool randomize_credentials; }; -enum Network ParseNetwork(std::string net); +enum Network ParseNetwork(const std::string& net); std::string GetNetworkName(enum Network net); bool SetProxy(enum Network net, const proxyType &addrProxy); bool GetProxy(enum Network net, proxyType &proxyInfoOut); diff --git a/src/rpc/masternode.cpp b/src/rpc/masternode.cpp index 8a11dc91e6..e1dddafb5a 100644 --- a/src/rpc/masternode.cpp +++ b/src/rpc/masternode.cpp @@ -564,7 +564,7 @@ static UniValue masternodelist(const JSONRPCRequest& request) if (!request.params[0].isNull()) strMode = request.params[0].get_str(); if (!request.params[1].isNull()) strFilter = request.params[1].get_str(); - std::transform(strMode.begin(), strMode.end(), strMode.begin(), ToLower); + strMode = ToLower(strMode); if (request.fHelp || ( strMode != "addr" && strMode != "full" && strMode != "info" && strMode != "json" && diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 80cf9fc556..569d15a569 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -188,7 +188,7 @@ bool ParseBoolV(const UniValue& v, const std::string &strName) else if (v.isStr()) strBool = v.get_str(); - std::transform(strBool.begin(), strBool.end(), strBool.begin(), ToLower); + strBool = ToLower(strBool); if (strBool == "true" || strBool == "yes" || strBool == "1") { return true; diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 72a7a4a182..9362f662d4 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1325,17 +1325,9 @@ BOOST_AUTO_TEST_CASE(test_ToLower) BOOST_CHECK_EQUAL(ToLower(0), 0); BOOST_CHECK_EQUAL(ToLower('\xff'), '\xff'); - std::string testVector; - Downcase(testVector); - BOOST_CHECK_EQUAL(testVector, ""); - - testVector = "#HODL"; - Downcase(testVector); - BOOST_CHECK_EQUAL(testVector, "#hodl"); - - testVector = "\x00\xfe\xff"; - Downcase(testVector); - BOOST_CHECK_EQUAL(testVector, "\x00\xfe\xff"); + BOOST_CHECK_EQUAL(ToLower(""), ""); + BOOST_CHECK_EQUAL(ToLower("#HODL"), "#hodl"); + BOOST_CHECK_EQUAL(ToLower("\x00\xfe\xff"), "\x00\xfe\xff"); } BOOST_AUTO_TEST_CASE(test_ToUpper) @@ -1346,6 +1338,10 @@ BOOST_AUTO_TEST_CASE(test_ToUpper) BOOST_CHECK_EQUAL(ToUpper('{'), '{'); BOOST_CHECK_EQUAL(ToUpper(0), 0); BOOST_CHECK_EQUAL(ToUpper('\xff'), '\xff'); + + BOOST_CHECK_EQUAL(ToUpper(""), ""); + BOOST_CHECK_EQUAL(ToUpper("#hodl"), "#HODL"); + BOOST_CHECK_EQUAL(ToUpper("\x00\xfe\xff"), "\x00\xfe\xff"); } BOOST_AUTO_TEST_CASE(test_Capitalize) diff --git a/src/util/strencodings.cpp b/src/util/strencodings.cpp index 6f05602fd7..cfb09e78eb 100644 --- a/src/util/strencodings.cpp +++ b/src/util/strencodings.cpp @@ -630,9 +630,18 @@ std::string HexStr(const Span s) return rv; } -void Downcase(std::string& str) +std::string ToLower(const std::string& str) { - std::transform(str.begin(), str.end(), str.begin(), [](char c){return ToLower(c);}); + std::string r; + for (auto ch : str) r += ToLower((unsigned char)ch); + return r; +} + +std::string ToUpper(const std::string& str) +{ + std::string r; + for (auto ch : str) r += ToUpper((unsigned char)ch); + return r; } std::string Capitalize(std::string str) diff --git a/src/util/strencodings.h b/src/util/strencodings.h index 79a5937713..54e4777fb5 100644 --- a/src/util/strencodings.h +++ b/src/util/strencodings.h @@ -203,6 +203,8 @@ bool ConvertBits(const O& outfn, I it, I end) { * Converts the given character to its lowercase equivalent. * This function is locale independent. It only converts uppercase * characters in the standard 7-bit ASCII range. + * This is a feature, not a limitation. + * * @param[in] c the character to convert to lowercase. * @return the lowercase equivalent of c; or the argument * if no conversion is possible. @@ -213,17 +215,22 @@ constexpr char ToLower(char c) } /** - * Converts the given string to its lowercase equivalent. + * Returns the lowercase equivalent of the given string. * This function is locale independent. It only converts uppercase * characters in the standard 7-bit ASCII range. - * @param[in,out] str the string to convert to lowercase. + * This is a feature, not a limitation. + * + * @param[in] str the string to convert to lowercase. + * @returns lowercased equivalent of str */ -void Downcase(std::string& str); +std::string ToLower(const std::string& str); /** * Converts the given character to its uppercase equivalent. * This function is locale independent. It only converts lowercase * characters in the standard 7-bit ASCII range. + * This is a feature, not a limitation. + * * @param[in] c the character to convert to uppercase. * @return the uppercase equivalent of c; or the argument * if no conversion is possible. @@ -233,13 +240,25 @@ constexpr char ToUpper(char c) return (c >= 'a' && c <= 'z' ? (c - 'a') + 'A' : c); } +/** + * Returns the uppercase equivalent of the given string. + * This function is locale independent. It only converts lowercase + * characters in the standard 7-bit ASCII range. + * This is a feature, not a limitation. + * + * @param[in] str the string to convert to uppercase. + * @returns UPPERCASED EQUIVALENT OF str + */ +std::string ToUpper(const std::string& str); + /** * Capitalizes the first character of the given string. - * This function is locale independent. It only capitalizes the - * first character of the argument if it has an uppercase equivalent - * in the standard 7-bit ASCII range. + * This function is locale independent. It only converts lowercase + * characters in the standard 7-bit ASCII range. + * This is a feature, not a limitation. + * * @param[in] str the string to capitalize. - * @return string with the first letter capitalized. + * @returns string with the first letter capitalized. */ std::string Capitalize(std::string str); diff --git a/src/util/system.cpp b/src/util/system.cpp index e08f0a2256..015220eed5 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -427,7 +427,7 @@ bool ArgsManager::ParseParameters(int argc, const char* const argv[], std::strin key.erase(is_index); } #ifdef WIN32 - std::transform(key.begin(), key.end(), key.begin(), ToLower); + key = ToLower(key); if (key[0] == '/') key[0] = '-'; #endif