fix(libc): stop the wcstol family at a binary prefix on Linux
wcstol, wcstoll, wcstoul and wcstoull parse the ASCII prefix of the guest's UTF-16 text with std::strtoll and std::strtoull, which glibc 2.38 and later bind to the C23 __isoc23_* functions: wcstol(u"0b101", &end, 0) returned 5 with the end pointer after the whole string. They now check StopAtBinaryPrefix_nid_no_patch first, like the narrow functions, and the end pointer maps back through ParseAsciiPrefix as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
b5c9945e1f
commit
8c714f76af
|
|
@ -423,19 +423,19 @@ long double APS5_VABI wcstold_nid_postfix(const char16_t* str, char16_t** endptr
|
|||
}
|
||||
|
||||
long long APS5_VABI wcstol_nid_postfix(const char16_t* str, char16_t** endptr, int base) {
|
||||
return ParseAsciiPrefix(str, endptr, [base](const char* text, char** end) { return std::strtoll(text, end, base); });
|
||||
return ParseAsciiPrefix(str, endptr, [base](const char* text, char** end) { return StopAtBinaryPrefix_nid_no_patch(text, end, base) ? 0LL : std::strtoll(text, end, base); });
|
||||
}
|
||||
|
||||
long long APS5_VABI wcstoll_nid_postfix(const char16_t* str, char16_t** endptr, int base) {
|
||||
return ParseAsciiPrefix(str, endptr, [base](const char* text, char** end) { return std::strtoll(text, end, base); });
|
||||
return ParseAsciiPrefix(str, endptr, [base](const char* text, char** end) { return StopAtBinaryPrefix_nid_no_patch(text, end, base) ? 0LL : std::strtoll(text, end, base); });
|
||||
}
|
||||
|
||||
unsigned long long APS5_VABI wcstoul_nid_postfix(const char16_t* str, char16_t** endptr, int base) {
|
||||
return ParseAsciiPrefix(str, endptr, [base](const char* text, char** end) { return std::strtoull(text, end, base); });
|
||||
return ParseAsciiPrefix(str, endptr, [base](const char* text, char** end) { return StopAtBinaryPrefix_nid_no_patch(text, end, base) ? 0ULL : std::strtoull(text, end, base); });
|
||||
}
|
||||
|
||||
unsigned long long APS5_VABI wcstoull_nid_postfix(const char16_t* str, char16_t** endptr, int base) {
|
||||
return ParseAsciiPrefix(str, endptr, [base](const char* text, char** end) { return std::strtoull(text, end, base); });
|
||||
return ParseAsciiPrefix(str, endptr, [base](const char* text, char** end) { return StopAtBinaryPrefix_nid_no_patch(text, end, base) ? 0ULL : std::strtoull(text, end, base); });
|
||||
}
|
||||
|
||||
int APS5_VABI wcscoll_nid_postfix(const char16_t* first, const char16_t* second) {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <climits>
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <initializer_list>
|
||||
|
||||
extern "C" {
|
||||
const char16_t* APS5_VABI wmemchr_nid_postfix(const char16_t* s, char16_t c, std::size_t n);
|
||||
|
|
@ -125,6 +126,14 @@ int main() {
|
|||
require(wcstoull_nid_postfix(u"18446744073709551615", nullptr, 10) == ULLONG_MAX);
|
||||
const char16_t* letters = u"abc";
|
||||
require(wcstol_nid_postfix(letters, &end, 10) == 0 && end == letters);
|
||||
const char16_t* binary = u" -0b101";
|
||||
for (const int base : {0, 2}) {
|
||||
require(wcstol_nid_postfix(binary, &end, base) == 0 && end == binary + 3);
|
||||
require(wcstoll_nid_postfix(binary, &end, base) == 0 && end == binary + 3);
|
||||
require(wcstoul_nid_postfix(binary, &end, base) == 0 && end == binary + 3);
|
||||
require(wcstoull_nid_postfix(binary, &end, base) == 0 && end == binary + 3);
|
||||
}
|
||||
require(wcstoll_nid_postfix(binary + 2, &end, 16) == 0xb101 && end == binary + 7);
|
||||
|
||||
const char16_t* scientific = u"3.5e2!";
|
||||
require(wcstod_nid_postfix(scientific, &end) == 350.0 && end == scientific + 5);
|
||||
|
|
|
|||
Loading…
Reference in New Issue