mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-12 15:09:59 +01:00
Replace use of locale dependent atoi(…) with locale-independent std::from_chars(…) (C++17)
test: Add test cases for LocaleIndependentAtoi fuzz: Assert legacy atoi(s) == LocaleIndependentAtoi<int>(s) fuzz: Assert legacy atoi64(s) == LocaleIndependentAtoi<int64_t>(s)
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <attributes.h>
|
||||
#include <span.h>
|
||||
#include <util/string.h>
|
||||
|
||||
#include <charconv>
|
||||
#include <cstdint>
|
||||
@@ -68,8 +69,33 @@ std::string EncodeBase32(Span<const unsigned char> input, bool pad = true);
|
||||
std::string EncodeBase32(const std::string& str, bool pad = true);
|
||||
|
||||
void SplitHostPort(std::string in, uint16_t& portOut, std::string& hostOut);
|
||||
int64_t atoi64(const std::string& str);
|
||||
int atoi(const std::string& str);
|
||||
|
||||
// LocaleIndependentAtoi is provided for backwards compatibility reasons.
|
||||
//
|
||||
// New code should use the ParseInt64/ParseUInt64/ParseInt32/ParseUInt32 functions
|
||||
// which provide parse error feedback.
|
||||
//
|
||||
// The goal of LocaleIndependentAtoi is to replicate the exact defined behaviour
|
||||
// of atoi and atoi64 as they behave under the "C" locale.
|
||||
template <typename T>
|
||||
T LocaleIndependentAtoi(const std::string& str)
|
||||
{
|
||||
static_assert(std::is_integral<T>::value);
|
||||
T result;
|
||||
// Emulate atoi(...) handling of white space and leading +/-.
|
||||
std::string s = TrimString(str);
|
||||
if (!s.empty() && s[0] == '+') {
|
||||
if (s.length() >= 2 && s[1] == '-') {
|
||||
return 0;
|
||||
}
|
||||
s = s.substr(1);
|
||||
}
|
||||
auto [_, error_condition] = std::from_chars(s.data(), s.data() + s.size(), result);
|
||||
if (error_condition != std::errc{}) {
|
||||
return 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the given character is a decimal digit.
|
||||
|
||||
Reference in New Issue
Block a user