From f6d25a3a81e5f545c744f37c11d86e9b29d22994 Mon Sep 17 00:00:00 2001 From: Andrew Aldridge Date: Thu, 11 Jan 2018 21:22:52 +0000 Subject: [PATCH] strtod: Do not consume "x" in incomplete hex input Adapted from upstream glibc commits: * 405698e946dbed472491f85867eb511eb080e05a * 43b9d657408fbf47a47934f9e7c84ed87f7f5a18 Fixes #13949 --- .../libroot/posix/glibc/stdlib/strtod.c | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/system/libroot/posix/glibc/stdlib/strtod.c b/src/system/libroot/posix/glibc/stdlib/strtod.c index 85642b89cf..b5d82692ab 100644 --- a/src/system/libroot/posix/glibc/stdlib/strtod.c +++ b/src/system/libroot/posix/glibc/stdlib/strtod.c @@ -674,18 +674,29 @@ INTERNAL (STRTOF) (nptr, endptr, group LOCALE_PARAM) /* If no other digit but a '0' is found the result is 0.0. Return current read pointer. */ - if ((c < L_('0') || c > L_('9')) - && (base == 16 && (c < TOLOWER (L_('a')) || c > TOLOWER (L_('f')))) + if (!((c >= L_('0') && c <= L_('9')) + || (base == 16 && ((CHAR_TYPE) TOLOWER (c) >= L_('a') + && (CHAR_TYPE) TOLOWER (c) <= L_('f'))) + || ( #ifdef USE_WIDE_CHAR - && c != decimal + c == (wint_t) decimal #else - && ({ for (cnt = 0; decimal[cnt] != '\0'; ++cnt) - if (decimal[cnt] != cp[cnt]) - break; - decimal[cnt] != '\0'; }) + ({ for (cnt = 0; decimal[cnt] != '\0'; ++cnt) + if (decimal[cnt] != cp[cnt]) + break; + decimal[cnt] == '\0'; }) #endif - && (base == 16 && (cp == start_of_digits || TOLOWER (c) != L_('p'))) - && (base != 16 && TOLOWER (c) != L_('e'))) + /* '0x.' alone is not a valid hexadecimal number. + '.' alone is not valid either, but that has been checked + already earlier. */ + && (base != 16 + || cp != start_of_digits + || (cp[decimal_len] >= L_('0') && cp[decimal_len] <= L_('9')) + || ((CHAR_TYPE) TOLOWER (cp[decimal_len]) >= L_('a') + && (CHAR_TYPE) TOLOWER (cp[decimal_len]) <= L_('f')))) + || (base == 16 && (cp != start_of_digits + && (CHAR_TYPE) TOLOWER (c) == L_('p'))) + || (base != 16 && (CHAR_TYPE) TOLOWER (c) == L_('e')))) { tp = correctly_grouped_prefix (start_of_digits, cp, thousands, grouping); /* If TP is at the start of the digits, there was no correctly