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:
practicalswift
2021-09-30 14:18:50 +00:00
parent 2d8e0c0c3c
commit 4343f114cc
15 changed files with 145 additions and 52 deletions

View File

@@ -122,6 +122,12 @@ bool LegacyParseUInt64(const std::string& str, uint64_t* out)
return endp && *endp == 0 && !errno &&
n <= std::numeric_limits<uint64_t>::max();
}
// For backwards compatibility checking.
int64_t atoi64_legacy(const std::string& str)
{
return strtoll(str.c_str(), nullptr, 10);
}
}; // namespace
FUZZ_TARGET(string)
@@ -268,4 +274,22 @@ FUZZ_TARGET(string)
assert(u8 == u8_legacy);
}
}
{
const int atoi_result = atoi(random_string_1.c_str());
const int locale_independent_atoi_result = LocaleIndependentAtoi<int>(random_string_1);
const int64_t atoi64_result = atoi64_legacy(random_string_1);
const bool out_of_range = atoi64_result < std::numeric_limits<int>::min() || atoi64_result > std::numeric_limits<int>::max();
if (out_of_range) {
assert(locale_independent_atoi_result == 0);
} else {
assert(atoi_result == locale_independent_atoi_result);
}
}
{
const int64_t atoi64_result = atoi64_legacy(random_string_1);
const int64_t locale_independent_atoi_result = LocaleIndependentAtoi<int64_t>(random_string_1);
assert(atoi64_result == locale_independent_atoi_result || locale_independent_atoi_result == 0);
}
}