Correct fish_wcstod and fix Linux build failure

Limit the fish_wcstod fast path to ASCII digits only, to fix the problem
observed in the discussion for a700acadfa
where LANG=de_DE.UTF-8 would cause `test` to interpret commas instead of
periods inside floating point values.
This commit is contained in:
ridiculousfish 2018-11-06 22:59:11 -08:00
parent db1500bfa4
commit bfd50863b8
2 changed files with 6 additions and 3 deletions

View file

@ -6,6 +6,7 @@
#include <errno.h>
#include <libgen.h>
#include <limits.h>
#include <math.h>
#include <pthread.h>
#include <signal.h>
#include <stdarg.h>

View file

@ -705,10 +705,12 @@ unsigned long long fish_wcstoull(const wchar_t *str, const wchar_t **endptr, int
double fish_wcstod(const wchar_t *str, wchar_t **endptr) {
// The "fast path." If we're all ASCII and we fit inline, use strtod().
char narrow[128];
size_t len_plus_0 = 1 + wcslen(str);
auto is_ascii = [](wchar_t c) { return c >= 0 && c <= 127; };
if (len_plus_0 <= sizeof narrow && std::all_of(str, str + len_plus_0, is_ascii)) {
size_t len = wcslen(str);
size_t len_plus_0 = 1 + len;
auto is_digit = [](wchar_t c) { return '0' <= c && c <= '9'; };
if (len_plus_0 <= sizeof narrow && std::all_of(str, str + len, is_digit)) {
// Fast path. Copy the string into a local buffer and run strtod() on it.
// We can ignore the locale-taking version because we are limited to ASCII digits.
std::copy(str, str + len_plus_0, narrow);
char *narrow_endptr = nullptr;
double ret = strtod(narrow, endptr ? &narrow_endptr : nullptr);