mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 04:22:55 +01:00
Merge #14585: refactor: remove usage of locale dependent std::isspace
15db77f4dd Don't rely on locale dependent functions in base_blob<BITS>::SetHex(...) (uint256), DecodeBase58(...), ParseMoney(...) and ParseHex(...) (practicalswift) Pull request description: Don't rely on locale dependent function `std::isspace` in `base_blob<BITS>::SetHex(...)` (uint256), `DecodeBase58(...)`, `ParseMoney(...)` and `ParseHex(...)`. Rationale: ``` $ uname -s Darwin $ cat poc.cpp #include <iostream> #include <locale> int main(void) { setlocale(LC_ALL, ""); std::cout << std::isspace(133) << ' ' << std::isspace(154) << ' ' << std::isspace(160); std::cout << '\n'; } $ clang++ -o poc poc.cpp $ ./poc 1 0 1 $ LC_ALL=en_US ./poc 1 0 1 $ LC_ALL=C ./poc 0 0 0 $ LC_ALL=ru_RU.KOI8-R ./poc # an "interesting" locale 0 1 0 ``` Tree-SHA512: 4eafb267342b8a777da6cca07c353afd1f90f3fc1d91e01f526f1b384a2b97c1da25b7bd7dfc300655182a4eaec6a4bea855a45723ab53c750a734b60e1e3c9f
This commit is contained in:
parent
39933ecd8a
commit
6bb5dfe2d9
@ -36,7 +36,7 @@ static const int8_t mapBase58[256] = {
|
|||||||
bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
|
bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
|
||||||
{
|
{
|
||||||
// Skip leading spaces.
|
// Skip leading spaces.
|
||||||
while (*psz && isspace(*psz))
|
while (*psz && IsSpace(*psz))
|
||||||
psz++;
|
psz++;
|
||||||
// Skip and count leading '1's.
|
// Skip and count leading '1's.
|
||||||
int zeroes = 0;
|
int zeroes = 0;
|
||||||
@ -50,7 +50,7 @@ bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
|
|||||||
std::vector<unsigned char> b256(size);
|
std::vector<unsigned char> b256(size);
|
||||||
// Process the characters.
|
// Process the characters.
|
||||||
static_assert(sizeof(mapBase58)/sizeof(mapBase58[0]) == 256, "mapBase58.size() should be 256"); // guarantee not out of range
|
static_assert(sizeof(mapBase58)/sizeof(mapBase58[0]) == 256, "mapBase58.size() should be 256"); // guarantee not out of range
|
||||||
while (*psz && !isspace(*psz)) {
|
while (*psz && !IsSpace(*psz)) {
|
||||||
// Decode base58 character
|
// Decode base58 character
|
||||||
int carry = mapBase58[(uint8_t)*psz];
|
int carry = mapBase58[(uint8_t)*psz];
|
||||||
if (carry == -1) // Invalid b58 character
|
if (carry == -1) // Invalid b58 character
|
||||||
@ -66,7 +66,7 @@ bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
|
|||||||
psz++;
|
psz++;
|
||||||
}
|
}
|
||||||
// Skip trailing spaces.
|
// Skip trailing spaces.
|
||||||
while (isspace(*psz))
|
while (IsSpace(*psz))
|
||||||
psz++;
|
psz++;
|
||||||
if (*psz != 0)
|
if (*psz != 0)
|
||||||
return false;
|
return false;
|
||||||
|
@ -33,7 +33,7 @@ void base_blob<BITS>::SetHex(const char* psz)
|
|||||||
memset(m_data, 0, sizeof(m_data));
|
memset(m_data, 0, sizeof(m_data));
|
||||||
|
|
||||||
// skip leading spaces
|
// skip leading spaces
|
||||||
while (isspace(*psz))
|
while (IsSpace(*psz))
|
||||||
psz++;
|
psz++;
|
||||||
|
|
||||||
// skip 0x
|
// skip 0x
|
||||||
|
@ -41,7 +41,7 @@ bool ParseMoney(const char* pszIn, CAmount& nRet)
|
|||||||
std::string strWhole;
|
std::string strWhole;
|
||||||
int64_t nUnits = 0;
|
int64_t nUnits = 0;
|
||||||
const char* p = pszIn;
|
const char* p = pszIn;
|
||||||
while (isspace(*p))
|
while (IsSpace(*p))
|
||||||
p++;
|
p++;
|
||||||
for (; *p; p++)
|
for (; *p; p++)
|
||||||
{
|
{
|
||||||
@ -56,14 +56,14 @@ bool ParseMoney(const char* pszIn, CAmount& nRet)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (isspace(*p))
|
if (IsSpace(*p))
|
||||||
break;
|
break;
|
||||||
if (!isdigit(*p))
|
if (!isdigit(*p))
|
||||||
return false;
|
return false;
|
||||||
strWhole.insert(strWhole.end(), *p);
|
strWhole.insert(strWhole.end(), *p);
|
||||||
}
|
}
|
||||||
for (; *p; p++)
|
for (; *p; p++)
|
||||||
if (!isspace(*p))
|
if (!IsSpace(*p))
|
||||||
return false;
|
return false;
|
||||||
if (strWhole.size() > 10) // guard against 63 bit overflow
|
if (strWhole.size() > 10) // guard against 63 bit overflow
|
||||||
return false;
|
return false;
|
||||||
|
@ -87,7 +87,7 @@ std::vector<unsigned char> ParseHex(const char* psz)
|
|||||||
std::vector<unsigned char> vch;
|
std::vector<unsigned char> vch;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
while (isspace(*psz))
|
while (IsSpace(*psz))
|
||||||
psz++;
|
psz++;
|
||||||
signed char c = HexDigit(*psz++);
|
signed char c = HexDigit(*psz++);
|
||||||
if (c == (signed char)-1)
|
if (c == (signed char)-1)
|
||||||
@ -272,7 +272,7 @@ std::string DecodeBase32(const std::string& str, bool* pf_invalid)
|
|||||||
{
|
{
|
||||||
if (str.empty()) // No empty string allowed
|
if (str.empty()) // No empty string allowed
|
||||||
return false;
|
return false;
|
||||||
if (str.size() >= 1 && (isspace(str[0]) || isspace(str[str.size()-1]))) // No padding allowed
|
if (str.size() >= 1 && (IsSpace(str[0]) || IsSpace(str[str.size()-1]))) // No padding allowed
|
||||||
return false;
|
return false;
|
||||||
if (!ValidAsCString(str)) // No embedded NUL characters allowed
|
if (!ValidAsCString(str)) // No embedded NUL characters allowed
|
||||||
return false;
|
return false;
|
||||||
|
@ -84,6 +84,21 @@ constexpr bool IsDigit(char c)
|
|||||||
return c >= '0' && c <= '9';
|
return c >= '0' && c <= '9';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* Convert string to signed 32-bit integer with strict parse error feedback.
|
||||||
* @returns true if the entire string could be parsed as valid integer,
|
* @returns true if the entire string could be parsed as valid integer,
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
export LC_ALL=C
|
export LC_ALL=C
|
||||||
|
|
||||||
KNOWN_VIOLATIONS=(
|
KNOWN_VIOLATIONS=(
|
||||||
"src/base58.cpp:.*isspace"
|
|
||||||
"src/bench/string_cast.cpp.*atoi"
|
"src/bench/string_cast.cpp.*atoi"
|
||||||
"src/dash-tx.cpp.*stoul"
|
"src/dash-tx.cpp.*stoul"
|
||||||
"src/dash-tx.cpp.*trim_right"
|
"src/dash-tx.cpp.*trim_right"
|
||||||
@ -29,14 +28,11 @@ KNOWN_VIOLATIONS=(
|
|||||||
"src/test/getarg_tests.cpp.*split"
|
"src/test/getarg_tests.cpp.*split"
|
||||||
"src/torcontrol.cpp:.*atoi"
|
"src/torcontrol.cpp:.*atoi"
|
||||||
"src/torcontrol.cpp:.*strtol"
|
"src/torcontrol.cpp:.*strtol"
|
||||||
"src/uint256.cpp:.*isspace"
|
|
||||||
"src/uint256.cpp:.*tolower"
|
"src/uint256.cpp:.*tolower"
|
||||||
"src/util/system.cpp:.*atoi"
|
"src/util/system.cpp:.*atoi"
|
||||||
"src/util/system.cpp:.*tolower"
|
"src/util/system.cpp:.*tolower"
|
||||||
"src/util/moneystr.cpp:.*isdigit"
|
"src/util/moneystr.cpp:.*isdigit"
|
||||||
"src/util/moneystr.cpp:.*isspace"
|
|
||||||
"src/util/strencodings.cpp:.*atoi"
|
"src/util/strencodings.cpp:.*atoi"
|
||||||
"src/util/strencodings.cpp:.*isspace"
|
|
||||||
"src/util/strencodings.cpp:.*strtol"
|
"src/util/strencodings.cpp:.*strtol"
|
||||||
"src/util/strencodings.cpp:.*strtoll"
|
"src/util/strencodings.cpp:.*strtoll"
|
||||||
"src/util/strencodings.cpp:.*strtoul"
|
"src/util/strencodings.cpp:.*strtoul"
|
||||||
|
Loading…
Reference in New Issue
Block a user