diff --git a/src/base58.cpp b/src/base58.cpp --- a/src/base58.cpp +++ b/src/base58.cpp @@ -7,6 +7,7 @@ #include "hash.h" #include "script/script.h" #include "uint256.h" +#include "utilstrencodings.h" #include #include @@ -22,7 +23,7 @@ bool DecodeBase58(const char *psz, std::vector &vch) { // Skip leading spaces. - while (*psz && isspace(*psz)) { + while (*psz && IsSpace(*psz)) { psz++; } // Skip and count leading '1's. @@ -37,7 +38,7 @@ int size = strlen(psz) * 733 / 1000 + 1; std::vector b256(size); // Process the characters. - while (*psz && !isspace(*psz)) { + while (*psz && !IsSpace(*psz)) { // Decode base58 character const char *ch = strchr(pszBase58, *psz); if (ch == nullptr) { @@ -57,7 +58,7 @@ psz++; } // Skip trailing spaces. - while (isspace(*psz)) { + while (IsSpace(*psz)) { psz++; } if (*psz != 0) { diff --git a/src/uint256.cpp b/src/uint256.cpp --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -25,7 +25,7 @@ memset(data, 0, sizeof(data)); // skip leading spaces - while (isspace(*psz)) { + while (IsSpace(*psz)) { psz++; } diff --git a/src/utilmoneystr.cpp b/src/utilmoneystr.cpp --- a/src/utilmoneystr.cpp +++ b/src/utilmoneystr.cpp @@ -39,7 +39,7 @@ std::string strWhole; Amount nUnits = Amount::zero(); const char *p = pszIn; - while (isspace(*p)) { + while (IsSpace(*p)) { p++; } for (; *p; p++) { @@ -52,7 +52,7 @@ } break; } - if (isspace(*p)) { + if (IsSpace(*p)) { break; } if (!isdigit(*p)) { @@ -61,7 +61,7 @@ strWhole.insert(strWhole.end(), *p); } for (; *p; p++) { - if (!isspace(*p)) { + if (!IsSpace(*p)) { return false; } } diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -67,6 +67,23 @@ int64_t atoi64(const std::string &str); int atoi(const std::string &str); +/** + * Tests if the given character is a whitespace character. The whitespace + * characters are: space, form-feed ('\f'), newline ('\n'), carriage return + * ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). + * + * This function is locale independent. Under the C locale this function gives + * the same result as std::isspace. + * + * @param[in] c character to test + * @return true if the argument is a whitespace character; otherwise + * false + */ +constexpr inline bool IsSpace(char c) noexcept { + return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || + c == '\v'; +} + /** * Convert string to signed 32-bit integer with strict parse error feedback. * @returns true if the entire string could be parsed as valid integer, false if diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -84,7 +84,7 @@ // convert hex dump to vector std::vector vch; while (true) { - while (isspace(*psz)) { + while (IsSpace(*psz)) { psz++; } signed char c = HexDigit(*psz++); @@ -471,7 +471,7 @@ return false; } // No padding allowed - if (str.size() >= 1 && (isspace(str[0]) || isspace(str[str.size() - 1]))) { + if (str.size() >= 1 && (IsSpace(str[0]) || IsSpace(str[str.size() - 1]))) { return false; } // No embedded NUL characters allowed diff --git a/test/lint/lint-locale-dependence.sh b/test/lint/lint-locale-dependence.sh --- a/test/lint/lint-locale-dependence.sh +++ b/test/lint/lint-locale-dependence.sh @@ -1,7 +1,6 @@ #!/usr/bin/env bash KNOWN_VIOLATIONS=( - "src/base58.cpp:.*isspace" "src/bitcoin-tx.cpp.*stoul" "src/bitcoin-tx.cpp.*trim_right" "src/bitcoin-tx.cpp:.*atoi" @@ -17,14 +16,11 @@ "src/test/dbwrapper_tests.cpp:.*snprintf" "src/test/getarg_tests.cpp.*split" "src/torcontrol.cpp:.*atoi" - "src/uint256.cpp:.*isspace" "src/uint256.cpp:.*tolower" "src/util.cpp:.*atoi" "src/util.cpp:.*tolower" "src/utilmoneystr.cpp:.*isdigit" - "src/utilmoneystr.cpp:.*isspace" "src/utilstrencodings.cpp:.*atoi" - "src/utilstrencodings.cpp:.*isspace" # Append the opening parenthesis to avoid shadowing strtoll with grep "src/utilstrencodings.cpp:.*strtol\(" "src/utilstrencodings.cpp:.*strtoll"