Skip to content

Commit

Permalink
Merge bitcoin#14585: refactor: remove usage of locale dependent std::…
Browse files Browse the repository at this point in the history
…isspace

15db77f 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
  • Loading branch information
MarcoFalke authored and PastaPastaPasta committed Aug 16, 2021
1 parent ea26a81 commit cdd53d4
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 13 deletions.
7 changes: 4 additions & 3 deletions src/base58.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <hash.h>
#include <uint256.h>
#include <utilstrencodings.h>

#include <assert.h>
#include <stdint.h>
Expand Down Expand Up @@ -34,7 +35,7 @@ static const int8_t mapBase58[256] = {
bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
{
// Skip leading spaces.
while (*psz && isspace(*psz))
while (*psz && IsSpace(*psz))
psz++;
// Skip and count leading '1's.
int zeroes = 0;
Expand All @@ -48,7 +49,7 @@ bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
std::vector<unsigned char> b256(size);
// Process the characters.
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
int carry = mapBase58[(uint8_t)*psz];
if (carry == -1) // Invalid b58 character
Expand All @@ -64,7 +65,7 @@ bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
psz++;
}
// Skip trailing spaces.
while (isspace(*psz))
while (IsSpace(*psz))
psz++;
if (*psz != 0)
return false;
Expand Down
2 changes: 1 addition & 1 deletion src/uint256.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ void base_blob<BITS>::SetHex(const char* psz)
memset(m_data, 0, sizeof(m_data));

// skip leading spaces
while (isspace(*psz))
while (IsSpace(*psz))
psz++;

// skip 0x
Expand Down
6 changes: 3 additions & 3 deletions src/utilmoneystr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ bool ParseMoney(const char* pszIn, CAmount& nRet)
std::string strWhole;
int64_t nUnits = 0;
const char* p = pszIn;
while (isspace(*p))
while (IsSpace(*p))
p++;
for (; *p; p++)
{
Expand All @@ -56,14 +56,14 @@ bool ParseMoney(const char* pszIn, CAmount& nRet)
}
break;
}
if (isspace(*p))
if (IsSpace(*p))
break;
if (!isdigit(*p))
return false;
strWhole.insert(strWhole.end(), *p);
}
for (; *p; p++)
if (!isspace(*p))
if (!IsSpace(*p))
return false;
if (strWhole.size() > 10) // guard against 63 bit overflow
return false;
Expand Down
4 changes: 2 additions & 2 deletions src/utilstrencodings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ std::vector<unsigned char> ParseHex(const char* psz)
std::vector<unsigned char> vch;
while (true)
{
while (isspace(*psz))
while (IsSpace(*psz))
psz++;
signed char c = HexDigit(*psz++);
if (c == (signed char)-1)
Expand Down Expand Up @@ -265,7 +265,7 @@ NODISCARD static bool ParsePrechecks(const std::string& str)
{
if (str.empty()) // No empty string allowed
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;
if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed
return false;
Expand Down
15 changes: 15 additions & 0 deletions src/utilstrencodings.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,21 @@ constexpr bool IsDigit(char c)
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.
* @returns true if the entire string could be parsed as valid integer,
Expand Down
4 changes: 0 additions & 4 deletions test/lint/lint-locale-dependence.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
export LC_ALL=C

KNOWN_VIOLATIONS=(
"src/base58.cpp:.*isspace"
"src/bench/string_cast.cpp.*atoi"
"src/dash-tx.cpp.*stoul"
"src/dash-tx.cpp.*trim_right"
Expand Down Expand Up @@ -31,15 +30,12 @@ KNOWN_VIOLATIONS=(
"src/test/getarg_tests.cpp.*split"
"src/torcontrol.cpp:.*atoi"
"src/torcontrol.cpp:.*strtol"
"src/uint256.cpp:.*isspace"
"src/uint256.cpp:.*tolower"
"src/util.cpp:.*atoi"
"src/util.cpp:.*fprintf"
"src/util.cpp:.*tolower"
"src/utilmoneystr.cpp:.*isdigit"
"src/utilmoneystr.cpp:.*isspace"
"src/utilstrencodings.cpp:.*atoi"
"src/utilstrencodings.cpp:.*isspace"
"src/utilstrencodings.cpp:.*strtol"
"src/utilstrencodings.cpp:.*strtoll"
"src/utilstrencodings.cpp:.*strtoul"
Expand Down

0 comments on commit cdd53d4

Please sign in to comment.