421842aad7
CVE-2014-9761: unbounded stack allocation in nan* functions
926 lines
35 KiB
Diff
926 lines
35 KiB
Diff
commit e02cabecf0d025ec4f4ddee290bdf7aadb873bb3
|
||
Author: Joseph Myers <joseph@codesourcery.com>
|
||
Date: Tue Nov 24 22:24:52 2015 +0000
|
||
|
||
Refactor strtod parsing of NaN payloads.
|
||
|
||
The nan* functions handle their string argument by constructing a
|
||
NAN(...) string on the stack as a VLA and passing it to strtod
|
||
functions.
|
||
|
||
This approach has problems discussed in bug 16961 and bug 16962: the
|
||
stack usage is unbounded, and it gives incorrect results in certain
|
||
cases where the argument is not a valid n-char-sequence.
|
||
|
||
The natural fix for both issues is to refactor the NaN payload parsing
|
||
out of strtod into a separate function that the nan* functions can
|
||
call directly, so that no temporary string needs constructing on the
|
||
stack at all. This patch does that refactoring in preparation for
|
||
fixing those bugs (but without actually using the new functions from
|
||
nan* - which will also require exporting them from libc at version
|
||
GLIBC_PRIVATE). This patch is not intended to change any user-visible
|
||
behavior, so no tests are added (fixes for the above bugs will of
|
||
course add tests for them).
|
||
|
||
This patch builds on my recent fixes for strtol and strtod issues in
|
||
Turkish locales. Given those fixes, the parsing of NaN payloads is
|
||
locale-independent; thus, the new functions do not need to take a
|
||
locale_t argument.
|
||
|
||
Tested for x86_64, x86, mips64 and powerpc.
|
||
|
||
* stdlib/strtod_nan.c: New file.
|
||
* stdlib/strtod_nan_double.h: Likewise.
|
||
* stdlib/strtod_nan_float.h: Likewise.
|
||
* stdlib/strtod_nan_main.c: Likewise.
|
||
* stdlib/strtod_nan_narrow.h: Likewise.
|
||
* stdlib/strtod_nan_wide.h: Likewise.
|
||
* stdlib/strtof_nan.c: Likewise.
|
||
* stdlib/strtold_nan.c: Likewise.
|
||
* sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h: Likewise.
|
||
* sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h: Likewise.
|
||
* sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h: Likewise.
|
||
* wcsmbs/wcstod_nan.c: Likewise.
|
||
* wcsmbs/wcstof_nan.c: Likewise.
|
||
* wcsmbs/wcstold_nan.c: Likewise.
|
||
* stdlib/Makefile (routines): Add strtof_nan, strtod_nan and
|
||
strtold_nan.
|
||
* wcsmbs/Makefile (routines): Add wcstod_nan, wcstold_nan and
|
||
wcstof_nan.
|
||
* include/stdlib.h (__strtof_nan): Declare and use
|
||
libc_hidden_proto.
|
||
(__strtod_nan): Likewise.
|
||
(__strtold_nan): Likewise.
|
||
(__wcstof_nan): Likewise.
|
||
(__wcstod_nan): Likewise.
|
||
(__wcstold_nan): Likewise.
|
||
* include/wchar.h (____wcstoull_l_internal): Declare.
|
||
* stdlib/strtod_l.c: Do not include <ieee754.h>.
|
||
(____strtoull_l_internal): Remove declaration.
|
||
(STRTOF_NAN): Define macro.
|
||
(SET_MANTISSA): Remove macro.
|
||
(STRTOULL): Likewise.
|
||
(____STRTOF_INTERNAL): Use STRTOF_NAN to parse NaN payload.
|
||
* stdlib/strtof_l.c (____strtoull_l_internal): Remove declaration.
|
||
(STRTOF_NAN): Define macro.
|
||
(SET_MANTISSA): Remove macro.
|
||
* sysdeps/ieee754/ldbl-128/strtold_l.c (STRTOF_NAN): Define macro.
|
||
(SET_MANTISSA): Remove macro.
|
||
* sysdeps/ieee754/ldbl-128ibm/strtold_l.c (STRTOF_NAN): Define
|
||
macro.
|
||
(SET_MANTISSA): Remove macro.
|
||
* sysdeps/ieee754/ldbl-64-128/strtold_l.c (STRTOF_NAN): Define
|
||
macro.
|
||
(SET_MANTISSA): Remove macro.
|
||
* sysdeps/ieee754/ldbl-96/strtold_l.c (STRTOF_NAN): Define macro.
|
||
(SET_MANTISSA): Remove macro.
|
||
* wcsmbs/wcstod_l.c (____wcstoull_l_internal): Remove declaration.
|
||
* wcsmbs/wcstof_l.c (____wcstoull_l_internal): Likewise.
|
||
* wcsmbs/wcstold_l.c (____wcstoull_l_internal): Likewise.
|
||
|
||
Index: b/include/stdlib.h
|
||
===================================================================
|
||
--- a/include/stdlib.h
|
||
+++ b/include/stdlib.h
|
||
@@ -203,6 +203,24 @@ libc_hidden_proto (strtoll)
|
||
libc_hidden_proto (strtoul)
|
||
libc_hidden_proto (strtoull)
|
||
|
||
+extern float __strtof_nan (const char *, char **, char) internal_function;
|
||
+extern double __strtod_nan (const char *, char **, char) internal_function;
|
||
+extern long double __strtold_nan (const char *, char **, char)
|
||
+ internal_function;
|
||
+extern float __wcstof_nan (const wchar_t *, wchar_t **, wchar_t)
|
||
+ internal_function;
|
||
+extern double __wcstod_nan (const wchar_t *, wchar_t **, wchar_t)
|
||
+ internal_function;
|
||
+extern long double __wcstold_nan (const wchar_t *, wchar_t **, wchar_t)
|
||
+ internal_function;
|
||
+
|
||
+libc_hidden_proto (__strtof_nan)
|
||
+libc_hidden_proto (__strtod_nan)
|
||
+libc_hidden_proto (__strtold_nan)
|
||
+libc_hidden_proto (__wcstof_nan)
|
||
+libc_hidden_proto (__wcstod_nan)
|
||
+libc_hidden_proto (__wcstold_nan)
|
||
+
|
||
extern char *__ecvt (double __value, int __ndigit, int *__restrict __decpt,
|
||
int *__restrict __sign);
|
||
extern char *__fcvt (double __value, int __ndigit, int *__restrict __decpt,
|
||
Index: b/include/wchar.h
|
||
===================================================================
|
||
--- a/include/wchar.h
|
||
+++ b/include/wchar.h
|
||
@@ -52,6 +52,9 @@ extern unsigned long long int __wcstoull
|
||
__restrict __endptr,
|
||
int __base,
|
||
int __group) __THROW;
|
||
+extern unsigned long long int ____wcstoull_l_internal (const wchar_t *,
|
||
+ wchar_t **, int, int,
|
||
+ __locale_t);
|
||
libc_hidden_proto (__wcstof_internal)
|
||
libc_hidden_proto (__wcstod_internal)
|
||
libc_hidden_proto (__wcstold_internal)
|
||
Index: b/stdlib/Makefile
|
||
===================================================================
|
||
--- a/stdlib/Makefile
|
||
+++ b/stdlib/Makefile
|
||
@@ -50,6 +50,7 @@ routines := \
|
||
strtol_l strtoul_l strtoll_l strtoull_l \
|
||
strtof strtod strtold \
|
||
strtof_l strtod_l strtold_l \
|
||
+ strtof_nan strtod_nan strtold_nan \
|
||
system canonicalize \
|
||
a64l l64a \
|
||
rpmatch strfmon strfmon_l getsubopt xpg_basename fmtmsg \
|
||
Index: b/stdlib/strtod_l.c
|
||
===================================================================
|
||
--- a/stdlib/strtod_l.c
|
||
+++ b/stdlib/strtod_l.c
|
||
@@ -20,8 +20,6 @@
|
||
#include <xlocale.h>
|
||
|
||
extern double ____strtod_l_internal (const char *, char **, int, __locale_t);
|
||
-extern unsigned long long int ____strtoull_l_internal (const char *, char **,
|
||
- int, int, __locale_t);
|
||
|
||
/* Configuration part. These macros are defined by `strtold.c',
|
||
`strtof.c', `wcstod.c', `wcstold.c', and `wcstof.c' to produce the
|
||
@@ -33,27 +31,20 @@ extern unsigned long long int ____strtou
|
||
# ifdef USE_WIDE_CHAR
|
||
# define STRTOF wcstod_l
|
||
# define __STRTOF __wcstod_l
|
||
+# define STRTOF_NAN __wcstod_nan
|
||
# else
|
||
# define STRTOF strtod_l
|
||
# define __STRTOF __strtod_l
|
||
+# define STRTOF_NAN __strtod_nan
|
||
# endif
|
||
# define MPN2FLOAT __mpn_construct_double
|
||
# define FLOAT_HUGE_VAL HUGE_VAL
|
||
-# define SET_MANTISSA(flt, mant) \
|
||
- do { union ieee754_double u; \
|
||
- u.d = (flt); \
|
||
- u.ieee_nan.mantissa0 = (mant) >> 32; \
|
||
- u.ieee_nan.mantissa1 = (mant); \
|
||
- if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0) \
|
||
- (flt) = u.d; \
|
||
- } while (0)
|
||
#endif
|
||
/* End of configuration part. */
|
||
|
||
#include <ctype.h>
|
||
#include <errno.h>
|
||
#include <float.h>
|
||
-#include <ieee754.h>
|
||
#include "../locale/localeinfo.h"
|
||
#include <locale.h>
|
||
#include <math.h>
|
||
@@ -104,7 +95,6 @@ extern unsigned long long int ____strtou
|
||
# define TOLOWER_C(Ch) __towlower_l ((Ch), _nl_C_locobj_ptr)
|
||
# define STRNCASECMP(S1, S2, N) \
|
||
__wcsncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr)
|
||
-# define STRTOULL(S, E, B) ____wcstoull_l_internal ((S), (E), (B), 0, loc)
|
||
#else
|
||
# define STRING_TYPE char
|
||
# define CHAR_TYPE char
|
||
@@ -116,7 +106,6 @@ extern unsigned long long int ____strtou
|
||
# define TOLOWER_C(Ch) __tolower_l ((Ch), _nl_C_locobj_ptr)
|
||
# define STRNCASECMP(S1, S2, N) \
|
||
__strncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr)
|
||
-# define STRTOULL(S, E, B) ____strtoull_l_internal ((S), (E), (B), 0, loc)
|
||
#endif
|
||
|
||
|
||
@@ -655,33 +644,14 @@ ____STRTOF_INTERNAL (nptr, endptr, group
|
||
if (*cp == L_('('))
|
||
{
|
||
const STRING_TYPE *startp = cp;
|
||
- do
|
||
- ++cp;
|
||
- while ((*cp >= L_('0') && *cp <= L_('9'))
|
||
- || (*cp >= L_('A') && *cp <= L_('Z'))
|
||
- || (*cp >= L_('a') && *cp <= L_('z'))
|
||
- || *cp == L_('_'));
|
||
-
|
||
- if (*cp != L_(')'))
|
||
- /* The closing brace is missing. Only match the NAN
|
||
- part. */
|
||
- cp = startp;
|
||
+ STRING_TYPE *endp;
|
||
+ retval = STRTOF_NAN (cp + 1, &endp, L_(')'));
|
||
+ if (*endp == L_(')'))
|
||
+ /* Consume the closing parenthesis. */
|
||
+ cp = endp + 1;
|
||
else
|
||
- {
|
||
- /* This is a system-dependent way to specify the
|
||
- bitmask used for the NaN. We expect it to be
|
||
- a number which is put in the mantissa of the
|
||
- number. */
|
||
- STRING_TYPE *endp;
|
||
- unsigned long long int mant;
|
||
-
|
||
- mant = STRTOULL (startp + 1, &endp, 0);
|
||
- if (endp == cp)
|
||
- SET_MANTISSA (retval, mant);
|
||
-
|
||
- /* Consume the closing brace. */
|
||
- ++cp;
|
||
- }
|
||
+ /* Only match the NAN part. */
|
||
+ cp = startp;
|
||
}
|
||
|
||
if (endptr != NULL)
|
||
Index: b/stdlib/strtod_nan.c
|
||
===================================================================
|
||
--- /dev/null
|
||
+++ b/stdlib/strtod_nan.c
|
||
@@ -0,0 +1,24 @@
|
||
+/* Convert string for NaN payload to corresponding NaN. Narrow
|
||
+ strings, double.
|
||
+ Copyright (C) 2015 Free Software Foundation, Inc.
|
||
+ This file is part of the GNU C Library.
|
||
+
|
||
+ The GNU C Library is free software; you can redistribute it and/or
|
||
+ modify it under the terms of the GNU Lesser General Public
|
||
+ License as published by the Free Software Foundation; either
|
||
+ version 2.1 of the License, or (at your option) any later version.
|
||
+
|
||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
+ Lesser General Public License for more details.
|
||
+
|
||
+ You should have received a copy of the GNU Lesser General Public
|
||
+ License along with the GNU C Library; if not, see
|
||
+ <http://www.gnu.org/licenses/>. */
|
||
+
|
||
+#include <strtod_nan_narrow.h>
|
||
+#include <strtod_nan_double.h>
|
||
+
|
||
+#define STRTOD_NAN __strtod_nan
|
||
+#include <strtod_nan_main.c>
|
||
Index: b/stdlib/strtod_nan_double.h
|
||
===================================================================
|
||
--- /dev/null
|
||
+++ b/stdlib/strtod_nan_double.h
|
||
@@ -0,0 +1,30 @@
|
||
+/* Convert string for NaN payload to corresponding NaN. For double.
|
||
+ Copyright (C) 1997-2015 Free Software Foundation, Inc.
|
||
+ This file is part of the GNU C Library.
|
||
+
|
||
+ The GNU C Library is free software; you can redistribute it and/or
|
||
+ modify it under the terms of the GNU Lesser General Public
|
||
+ License as published by the Free Software Foundation; either
|
||
+ version 2.1 of the License, or (at your option) any later version.
|
||
+
|
||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
+ Lesser General Public License for more details.
|
||
+
|
||
+ You should have received a copy of the GNU Lesser General Public
|
||
+ License along with the GNU C Library; if not, see
|
||
+ <http://www.gnu.org/licenses/>. */
|
||
+
|
||
+#define FLOAT double
|
||
+#define SET_MANTISSA(flt, mant) \
|
||
+ do \
|
||
+ { \
|
||
+ union ieee754_double u; \
|
||
+ u.d = (flt); \
|
||
+ u.ieee_nan.mantissa0 = (mant) >> 32; \
|
||
+ u.ieee_nan.mantissa1 = (mant); \
|
||
+ if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0) \
|
||
+ (flt) = u.d; \
|
||
+ } \
|
||
+ while (0)
|
||
Index: b/stdlib/strtod_nan_float.h
|
||
===================================================================
|
||
--- /dev/null
|
||
+++ b/stdlib/strtod_nan_float.h
|
||
@@ -0,0 +1,29 @@
|
||
+/* Convert string for NaN payload to corresponding NaN. For float.
|
||
+ Copyright (C) 1997-2015 Free Software Foundation, Inc.
|
||
+ This file is part of the GNU C Library.
|
||
+
|
||
+ The GNU C Library is free software; you can redistribute it and/or
|
||
+ modify it under the terms of the GNU Lesser General Public
|
||
+ License as published by the Free Software Foundation; either
|
||
+ version 2.1 of the License, or (at your option) any later version.
|
||
+
|
||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
+ Lesser General Public License for more details.
|
||
+
|
||
+ You should have received a copy of the GNU Lesser General Public
|
||
+ License along with the GNU C Library; if not, see
|
||
+ <http://www.gnu.org/licenses/>. */
|
||
+
|
||
+#define FLOAT float
|
||
+#define SET_MANTISSA(flt, mant) \
|
||
+ do \
|
||
+ { \
|
||
+ union ieee754_float u; \
|
||
+ u.f = (flt); \
|
||
+ u.ieee_nan.mantissa = (mant); \
|
||
+ if (u.ieee.mantissa != 0) \
|
||
+ (flt) = u.f; \
|
||
+ } \
|
||
+ while (0)
|
||
Index: b/stdlib/strtod_nan_main.c
|
||
===================================================================
|
||
--- /dev/null
|
||
+++ b/stdlib/strtod_nan_main.c
|
||
@@ -0,0 +1,63 @@
|
||
+/* Convert string for NaN payload to corresponding NaN.
|
||
+ Copyright (C) 1997-2015 Free Software Foundation, Inc.
|
||
+ This file is part of the GNU C Library.
|
||
+
|
||
+ The GNU C Library is free software; you can redistribute it and/or
|
||
+ modify it under the terms of the GNU Lesser General Public
|
||
+ License as published by the Free Software Foundation; either
|
||
+ version 2.1 of the License, or (at your option) any later version.
|
||
+
|
||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
+ Lesser General Public License for more details.
|
||
+
|
||
+ You should have received a copy of the GNU Lesser General Public
|
||
+ License along with the GNU C Library; if not, see
|
||
+ <http://www.gnu.org/licenses/>. */
|
||
+
|
||
+#include <ieee754.h>
|
||
+#include <locale.h>
|
||
+#include <math.h>
|
||
+#include <stdlib.h>
|
||
+#include <wchar.h>
|
||
+
|
||
+
|
||
+/* If STR starts with an optional n-char-sequence as defined by ISO C
|
||
+ (a sequence of ASCII letters, digits and underscores), followed by
|
||
+ ENDC, return a NaN whose payload is set based on STR. Otherwise,
|
||
+ return a default NAN. If ENDPTR is not NULL, set *ENDPTR to point
|
||
+ to the character after the initial n-char-sequence. */
|
||
+
|
||
+internal_function
|
||
+FLOAT
|
||
+STRTOD_NAN (const STRING_TYPE *str, STRING_TYPE **endptr, STRING_TYPE endc)
|
||
+{
|
||
+ const STRING_TYPE *cp = str;
|
||
+
|
||
+ while ((*cp >= L_('0') && *cp <= L_('9'))
|
||
+ || (*cp >= L_('A') && *cp <= L_('Z'))
|
||
+ || (*cp >= L_('a') && *cp <= L_('z'))
|
||
+ || *cp == L_('_'))
|
||
+ ++cp;
|
||
+
|
||
+ FLOAT retval = NAN;
|
||
+ if (*cp != endc)
|
||
+ goto out;
|
||
+
|
||
+ /* This is a system-dependent way to specify the bitmask used for
|
||
+ the NaN. We expect it to be a number which is put in the
|
||
+ mantissa of the number. */
|
||
+ STRING_TYPE *endp;
|
||
+ unsigned long long int mant;
|
||
+
|
||
+ mant = STRTOULL (str, &endp, 0);
|
||
+ if (endp == cp)
|
||
+ SET_MANTISSA (retval, mant);
|
||
+
|
||
+ out:
|
||
+ if (endptr != NULL)
|
||
+ *endptr = (STRING_TYPE *) cp;
|
||
+ return retval;
|
||
+}
|
||
+libc_hidden_def (STRTOD_NAN)
|
||
Index: b/stdlib/strtod_nan_narrow.h
|
||
===================================================================
|
||
--- /dev/null
|
||
+++ b/stdlib/strtod_nan_narrow.h
|
||
@@ -0,0 +1,22 @@
|
||
+/* Convert string for NaN payload to corresponding NaN. Narrow strings.
|
||
+ Copyright (C) 1997-2015 Free Software Foundation, Inc.
|
||
+ This file is part of the GNU C Library.
|
||
+
|
||
+ The GNU C Library is free software; you can redistribute it and/or
|
||
+ modify it under the terms of the GNU Lesser General Public
|
||
+ License as published by the Free Software Foundation; either
|
||
+ version 2.1 of the License, or (at your option) any later version.
|
||
+
|
||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
+ Lesser General Public License for more details.
|
||
+
|
||
+ You should have received a copy of the GNU Lesser General Public
|
||
+ License along with the GNU C Library; if not, see
|
||
+ <http://www.gnu.org/licenses/>. */
|
||
+
|
||
+#define STRING_TYPE char
|
||
+#define L_(Ch) Ch
|
||
+#define STRTOULL(S, E, B) ____strtoull_l_internal ((S), (E), (B), 0, \
|
||
+ _nl_C_locobj_ptr)
|
||
Index: b/stdlib/strtod_nan_wide.h
|
||
===================================================================
|
||
--- /dev/null
|
||
+++ b/stdlib/strtod_nan_wide.h
|
||
@@ -0,0 +1,22 @@
|
||
+/* Convert string for NaN payload to corresponding NaN. Wide strings.
|
||
+ Copyright (C) 1997-2015 Free Software Foundation, Inc.
|
||
+ This file is part of the GNU C Library.
|
||
+
|
||
+ The GNU C Library is free software; you can redistribute it and/or
|
||
+ modify it under the terms of the GNU Lesser General Public
|
||
+ License as published by the Free Software Foundation; either
|
||
+ version 2.1 of the License, or (at your option) any later version.
|
||
+
|
||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
+ Lesser General Public License for more details.
|
||
+
|
||
+ You should have received a copy of the GNU Lesser General Public
|
||
+ License along with the GNU C Library; if not, see
|
||
+ <http://www.gnu.org/licenses/>. */
|
||
+
|
||
+#define STRING_TYPE wchar_t
|
||
+#define L_(Ch) L##Ch
|
||
+#define STRTOULL(S, E, B) ____wcstoull_l_internal ((S), (E), (B), 0, \
|
||
+ _nl_C_locobj_ptr)
|
||
Index: b/stdlib/strtof_l.c
|
||
===================================================================
|
||
--- a/stdlib/strtof_l.c
|
||
+++ b/stdlib/strtof_l.c
|
||
@@ -20,26 +20,19 @@
|
||
#include <xlocale.h>
|
||
|
||
extern float ____strtof_l_internal (const char *, char **, int, __locale_t);
|
||
-extern unsigned long long int ____strtoull_l_internal (const char *, char **,
|
||
- int, int, __locale_t);
|
||
|
||
#define FLOAT float
|
||
#define FLT FLT
|
||
#ifdef USE_WIDE_CHAR
|
||
# define STRTOF wcstof_l
|
||
# define __STRTOF __wcstof_l
|
||
+# define STRTOF_NAN __wcstof_nan
|
||
#else
|
||
# define STRTOF strtof_l
|
||
# define __STRTOF __strtof_l
|
||
+# define STRTOF_NAN __strtof_nan
|
||
#endif
|
||
#define MPN2FLOAT __mpn_construct_float
|
||
#define FLOAT_HUGE_VAL HUGE_VALF
|
||
-#define SET_MANTISSA(flt, mant) \
|
||
- do { union ieee754_float u; \
|
||
- u.f = (flt); \
|
||
- u.ieee_nan.mantissa = (mant); \
|
||
- if (u.ieee.mantissa != 0) \
|
||
- (flt) = u.f; \
|
||
- } while (0)
|
||
|
||
#include "strtod_l.c"
|
||
Index: b/stdlib/strtof_nan.c
|
||
===================================================================
|
||
--- /dev/null
|
||
+++ b/stdlib/strtof_nan.c
|
||
@@ -0,0 +1,24 @@
|
||
+/* Convert string for NaN payload to corresponding NaN. Narrow
|
||
+ strings, float.
|
||
+ Copyright (C) 2015 Free Software Foundation, Inc.
|
||
+ This file is part of the GNU C Library.
|
||
+
|
||
+ The GNU C Library is free software; you can redistribute it and/or
|
||
+ modify it under the terms of the GNU Lesser General Public
|
||
+ License as published by the Free Software Foundation; either
|
||
+ version 2.1 of the License, or (at your option) any later version.
|
||
+
|
||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
+ Lesser General Public License for more details.
|
||
+
|
||
+ You should have received a copy of the GNU Lesser General Public
|
||
+ License along with the GNU C Library; if not, see
|
||
+ <http://www.gnu.org/licenses/>. */
|
||
+
|
||
+#include <strtod_nan_narrow.h>
|
||
+#include <strtod_nan_float.h>
|
||
+
|
||
+#define STRTOD_NAN __strtof_nan
|
||
+#include <strtod_nan_main.c>
|
||
Index: b/stdlib/strtold_nan.c
|
||
===================================================================
|
||
--- /dev/null
|
||
+++ b/stdlib/strtold_nan.c
|
||
@@ -0,0 +1,30 @@
|
||
+/* Convert string for NaN payload to corresponding NaN. Narrow
|
||
+ strings, long double.
|
||
+ Copyright (C) 2015 Free Software Foundation, Inc.
|
||
+ This file is part of the GNU C Library.
|
||
+
|
||
+ The GNU C Library is free software; you can redistribute it and/or
|
||
+ modify it under the terms of the GNU Lesser General Public
|
||
+ License as published by the Free Software Foundation; either
|
||
+ version 2.1 of the License, or (at your option) any later version.
|
||
+
|
||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
+ Lesser General Public License for more details.
|
||
+
|
||
+ You should have received a copy of the GNU Lesser General Public
|
||
+ License along with the GNU C Library; if not, see
|
||
+ <http://www.gnu.org/licenses/>. */
|
||
+
|
||
+#include <math.h>
|
||
+
|
||
+/* This function is unused if long double and double have the same
|
||
+ representation. */
|
||
+#ifndef __NO_LONG_DOUBLE_MATH
|
||
+# include <strtod_nan_narrow.h>
|
||
+# include <strtod_nan_ldouble.h>
|
||
+
|
||
+# define STRTOD_NAN __strtold_nan
|
||
+# include <strtod_nan_main.c>
|
||
+#endif
|
||
Index: b/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h
|
||
===================================================================
|
||
--- /dev/null
|
||
+++ b/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h
|
||
@@ -0,0 +1,33 @@
|
||
+/* Convert string for NaN payload to corresponding NaN. For ldbl-128.
|
||
+ Copyright (C) 1997-2015 Free Software Foundation, Inc.
|
||
+ This file is part of the GNU C Library.
|
||
+
|
||
+ The GNU C Library is free software; you can redistribute it and/or
|
||
+ modify it under the terms of the GNU Lesser General Public
|
||
+ License as published by the Free Software Foundation; either
|
||
+ version 2.1 of the License, or (at your option) any later version.
|
||
+
|
||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
+ Lesser General Public License for more details.
|
||
+
|
||
+ You should have received a copy of the GNU Lesser General Public
|
||
+ License along with the GNU C Library; if not, see
|
||
+ <http://www.gnu.org/licenses/>. */
|
||
+
|
||
+#define FLOAT long double
|
||
+#define SET_MANTISSA(flt, mant) \
|
||
+ do \
|
||
+ { \
|
||
+ union ieee854_long_double u; \
|
||
+ u.d = (flt); \
|
||
+ u.ieee_nan.mantissa0 = 0; \
|
||
+ u.ieee_nan.mantissa1 = 0; \
|
||
+ u.ieee_nan.mantissa2 = (mant) >> 32; \
|
||
+ u.ieee_nan.mantissa3 = (mant); \
|
||
+ if ((u.ieee.mantissa0 | u.ieee.mantissa1 \
|
||
+ | u.ieee.mantissa2 | u.ieee.mantissa3) != 0) \
|
||
+ (flt) = u.d; \
|
||
+ } \
|
||
+ while (0)
|
||
Index: b/sysdeps/ieee754/ldbl-128/strtold_l.c
|
||
===================================================================
|
||
--- a/sysdeps/ieee754/ldbl-128/strtold_l.c
|
||
+++ b/sysdeps/ieee754/ldbl-128/strtold_l.c
|
||
@@ -25,22 +25,13 @@
|
||
#ifdef USE_WIDE_CHAR
|
||
# define STRTOF wcstold_l
|
||
# define __STRTOF __wcstold_l
|
||
+# define STRTOF_NAN __wcstold_nan
|
||
#else
|
||
# define STRTOF strtold_l
|
||
# define __STRTOF __strtold_l
|
||
+# define STRTOF_NAN __strtold_nan
|
||
#endif
|
||
#define MPN2FLOAT __mpn_construct_long_double
|
||
#define FLOAT_HUGE_VAL HUGE_VALL
|
||
-#define SET_MANTISSA(flt, mant) \
|
||
- do { union ieee854_long_double u; \
|
||
- u.d = (flt); \
|
||
- u.ieee_nan.mantissa0 = 0; \
|
||
- u.ieee_nan.mantissa1 = 0; \
|
||
- u.ieee_nan.mantissa2 = (mant) >> 32; \
|
||
- u.ieee_nan.mantissa3 = (mant); \
|
||
- if ((u.ieee.mantissa0 | u.ieee.mantissa1 \
|
||
- | u.ieee.mantissa2 | u.ieee.mantissa3) != 0) \
|
||
- (flt) = u.d; \
|
||
- } while (0)
|
||
|
||
#include <strtod_l.c>
|
||
Index: b/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h
|
||
===================================================================
|
||
--- /dev/null
|
||
+++ b/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h
|
||
@@ -0,0 +1,30 @@
|
||
+/* Convert string for NaN payload to corresponding NaN. For ldbl-128ibm.
|
||
+ Copyright (C) 1997-2015 Free Software Foundation, Inc.
|
||
+ This file is part of the GNU C Library.
|
||
+
|
||
+ The GNU C Library is free software; you can redistribute it and/or
|
||
+ modify it under the terms of the GNU Lesser General Public
|
||
+ License as published by the Free Software Foundation; either
|
||
+ version 2.1 of the License, or (at your option) any later version.
|
||
+
|
||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
+ Lesser General Public License for more details.
|
||
+
|
||
+ You should have received a copy of the GNU Lesser General Public
|
||
+ License along with the GNU C Library; if not, see
|
||
+ <http://www.gnu.org/licenses/>. */
|
||
+
|
||
+#define FLOAT long double
|
||
+#define SET_MANTISSA(flt, mant) \
|
||
+ do \
|
||
+ { \
|
||
+ union ibm_extended_long_double u; \
|
||
+ u.ld = (flt); \
|
||
+ u.d[0].ieee_nan.mantissa0 = (mant) >> 32; \
|
||
+ u.d[0].ieee_nan.mantissa1 = (mant); \
|
||
+ if ((u.d[0].ieee.mantissa0 | u.d[0].ieee.mantissa1) != 0) \
|
||
+ (flt) = u.ld; \
|
||
+ } \
|
||
+ while (0)
|
||
Index: b/sysdeps/ieee754/ldbl-128ibm/strtold_l.c
|
||
===================================================================
|
||
--- a/sysdeps/ieee754/ldbl-128ibm/strtold_l.c
|
||
+++ b/sysdeps/ieee754/ldbl-128ibm/strtold_l.c
|
||
@@ -30,25 +30,19 @@ extern long double ____new_wcstold_l (co
|
||
# define STRTOF __new_wcstold_l
|
||
# define __STRTOF ____new_wcstold_l
|
||
# define ____STRTOF_INTERNAL ____wcstold_l_internal
|
||
+# define STRTOF_NAN __wcstold_nan
|
||
#else
|
||
extern long double ____new_strtold_l (const char *, char **, __locale_t);
|
||
# define STRTOF __new_strtold_l
|
||
# define __STRTOF ____new_strtold_l
|
||
# define ____STRTOF_INTERNAL ____strtold_l_internal
|
||
+# define STRTOF_NAN __strtold_nan
|
||
#endif
|
||
extern __typeof (__STRTOF) STRTOF;
|
||
libc_hidden_proto (__STRTOF)
|
||
libc_hidden_proto (STRTOF)
|
||
#define MPN2FLOAT __mpn_construct_long_double
|
||
#define FLOAT_HUGE_VAL HUGE_VALL
|
||
-# define SET_MANTISSA(flt, mant) \
|
||
- do { union ibm_extended_long_double u; \
|
||
- u.ld = (flt); \
|
||
- u.d[0].ieee_nan.mantissa0 = (mant) >> 32; \
|
||
- u.d[0].ieee_nan.mantissa1 = (mant); \
|
||
- if ((u.d[0].ieee.mantissa0 | u.d[0].ieee.mantissa1) != 0) \
|
||
- (flt) = u.ld; \
|
||
- } while (0)
|
||
|
||
#include <strtod_l.c>
|
||
|
||
Index: b/sysdeps/ieee754/ldbl-64-128/strtold_l.c
|
||
===================================================================
|
||
--- a/sysdeps/ieee754/ldbl-64-128/strtold_l.c
|
||
+++ b/sysdeps/ieee754/ldbl-64-128/strtold_l.c
|
||
@@ -30,28 +30,19 @@ extern long double ____new_wcstold_l (co
|
||
# define STRTOF __new_wcstold_l
|
||
# define __STRTOF ____new_wcstold_l
|
||
# define ____STRTOF_INTERNAL ____wcstold_l_internal
|
||
+# define STRTOF_NAN __wcstold_nan
|
||
#else
|
||
extern long double ____new_strtold_l (const char *, char **, __locale_t);
|
||
# define STRTOF __new_strtold_l
|
||
# define __STRTOF ____new_strtold_l
|
||
# define ____STRTOF_INTERNAL ____strtold_l_internal
|
||
+# define STRTOF_NAN __strtold_nan
|
||
#endif
|
||
extern __typeof (__STRTOF) STRTOF;
|
||
libc_hidden_proto (__STRTOF)
|
||
libc_hidden_proto (STRTOF)
|
||
#define MPN2FLOAT __mpn_construct_long_double
|
||
#define FLOAT_HUGE_VAL HUGE_VALL
|
||
-#define SET_MANTISSA(flt, mant) \
|
||
- do { union ieee854_long_double u; \
|
||
- u.d = (flt); \
|
||
- u.ieee_nan.mantissa0 = 0; \
|
||
- u.ieee_nan.mantissa1 = 0; \
|
||
- u.ieee_nan.mantissa2 = (mant) >> 32; \
|
||
- u.ieee_nan.mantissa3 = (mant); \
|
||
- if ((u.ieee.mantissa0 | u.ieee.mantissa1 \
|
||
- | u.ieee.mantissa2 | u.ieee.mantissa3) != 0) \
|
||
- (flt) = u.d; \
|
||
- } while (0)
|
||
|
||
#include <strtod_l.c>
|
||
|
||
Index: b/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h
|
||
===================================================================
|
||
--- /dev/null
|
||
+++ b/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h
|
||
@@ -0,0 +1,30 @@
|
||
+/* Convert string for NaN payload to corresponding NaN. For ldbl-96.
|
||
+ Copyright (C) 1997-2015 Free Software Foundation, Inc.
|
||
+ This file is part of the GNU C Library.
|
||
+
|
||
+ The GNU C Library is free software; you can redistribute it and/or
|
||
+ modify it under the terms of the GNU Lesser General Public
|
||
+ License as published by the Free Software Foundation; either
|
||
+ version 2.1 of the License, or (at your option) any later version.
|
||
+
|
||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
+ Lesser General Public License for more details.
|
||
+
|
||
+ You should have received a copy of the GNU Lesser General Public
|
||
+ License along with the GNU C Library; if not, see
|
||
+ <http://www.gnu.org/licenses/>. */
|
||
+
|
||
+#define FLOAT long double
|
||
+#define SET_MANTISSA(flt, mant) \
|
||
+ do \
|
||
+ { \
|
||
+ union ieee854_long_double u; \
|
||
+ u.d = (flt); \
|
||
+ u.ieee_nan.mantissa0 = (mant) >> 32; \
|
||
+ u.ieee_nan.mantissa1 = (mant); \
|
||
+ if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0) \
|
||
+ (flt) = u.d; \
|
||
+ } \
|
||
+ while (0)
|
||
Index: b/sysdeps/ieee754/ldbl-96/strtold_l.c
|
||
===================================================================
|
||
--- a/sysdeps/ieee754/ldbl-96/strtold_l.c
|
||
+++ b/sysdeps/ieee754/ldbl-96/strtold_l.c
|
||
@@ -25,19 +25,13 @@
|
||
#ifdef USE_WIDE_CHAR
|
||
# define STRTOF wcstold_l
|
||
# define __STRTOF __wcstold_l
|
||
+# define STRTOF_NAN __wcstold_nan
|
||
#else
|
||
# define STRTOF strtold_l
|
||
# define __STRTOF __strtold_l
|
||
+# define STRTOF_NAN __strtold_nan
|
||
#endif
|
||
#define MPN2FLOAT __mpn_construct_long_double
|
||
#define FLOAT_HUGE_VAL HUGE_VALL
|
||
-#define SET_MANTISSA(flt, mant) \
|
||
- do { union ieee854_long_double u; \
|
||
- u.d = (flt); \
|
||
- u.ieee_nan.mantissa0 = (mant) >> 32; \
|
||
- u.ieee_nan.mantissa1 = (mant); \
|
||
- if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0) \
|
||
- (flt) = u.d; \
|
||
- } while (0)
|
||
|
||
#include <stdlib/strtod_l.c>
|
||
Index: b/wcsmbs/Makefile
|
||
===================================================================
|
||
--- a/wcsmbs/Makefile
|
||
+++ b/wcsmbs/Makefile
|
||
@@ -33,6 +33,7 @@ routines := wcscat wcschr wcscmp wcscpy
|
||
wcstol wcstoul wcstoll wcstoull wcstod wcstold wcstof \
|
||
wcstol_l wcstoul_l wcstoll_l wcstoull_l \
|
||
wcstod_l wcstold_l wcstof_l \
|
||
+ wcstod_nan wcstold_nan wcstof_nan \
|
||
wcscoll wcsxfrm \
|
||
wcwidth wcswidth \
|
||
wcscoll_l wcsxfrm_l \
|
||
Index: b/wcsmbs/wcstod_l.c
|
||
===================================================================
|
||
--- a/wcsmbs/wcstod_l.c
|
||
+++ b/wcsmbs/wcstod_l.c
|
||
@@ -23,9 +23,6 @@
|
||
|
||
extern double ____wcstod_l_internal (const wchar_t *, wchar_t **, int,
|
||
__locale_t);
|
||
-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *,
|
||
- wchar_t **, int, int,
|
||
- __locale_t);
|
||
|
||
#define USE_WIDE_CHAR 1
|
||
|
||
Index: b/wcsmbs/wcstod_nan.c
|
||
===================================================================
|
||
--- /dev/null
|
||
+++ b/wcsmbs/wcstod_nan.c
|
||
@@ -0,0 +1,23 @@
|
||
+/* Convert string for NaN payload to corresponding NaN. Wide strings, double.
|
||
+ Copyright (C) 2015 Free Software Foundation, Inc.
|
||
+ This file is part of the GNU C Library.
|
||
+
|
||
+ The GNU C Library is free software; you can redistribute it and/or
|
||
+ modify it under the terms of the GNU Lesser General Public
|
||
+ License as published by the Free Software Foundation; either
|
||
+ version 2.1 of the License, or (at your option) any later version.
|
||
+
|
||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
+ Lesser General Public License for more details.
|
||
+
|
||
+ You should have received a copy of the GNU Lesser General Public
|
||
+ License along with the GNU C Library; if not, see
|
||
+ <http://www.gnu.org/licenses/>. */
|
||
+
|
||
+#include "../stdlib/strtod_nan_wide.h"
|
||
+#include "../stdlib/strtod_nan_double.h"
|
||
+
|
||
+#define STRTOD_NAN __wcstod_nan
|
||
+#include "../stdlib/strtod_nan_main.c"
|
||
Index: b/wcsmbs/wcstof_l.c
|
||
===================================================================
|
||
--- a/wcsmbs/wcstof_l.c
|
||
+++ b/wcsmbs/wcstof_l.c
|
||
@@ -25,8 +25,5 @@
|
||
|
||
extern float ____wcstof_l_internal (const wchar_t *, wchar_t **, int,
|
||
__locale_t);
|
||
-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *,
|
||
- wchar_t **, int, int,
|
||
- __locale_t);
|
||
|
||
#include <stdlib/strtof_l.c>
|
||
Index: b/wcsmbs/wcstof_nan.c
|
||
===================================================================
|
||
--- /dev/null
|
||
+++ b/wcsmbs/wcstof_nan.c
|
||
@@ -0,0 +1,23 @@
|
||
+/* Convert string for NaN payload to corresponding NaN. Wide strings, float.
|
||
+ Copyright (C) 2015 Free Software Foundation, Inc.
|
||
+ This file is part of the GNU C Library.
|
||
+
|
||
+ The GNU C Library is free software; you can redistribute it and/or
|
||
+ modify it under the terms of the GNU Lesser General Public
|
||
+ License as published by the Free Software Foundation; either
|
||
+ version 2.1 of the License, or (at your option) any later version.
|
||
+
|
||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
+ Lesser General Public License for more details.
|
||
+
|
||
+ You should have received a copy of the GNU Lesser General Public
|
||
+ License along with the GNU C Library; if not, see
|
||
+ <http://www.gnu.org/licenses/>. */
|
||
+
|
||
+#include "../stdlib/strtod_nan_wide.h"
|
||
+#include "../stdlib/strtod_nan_float.h"
|
||
+
|
||
+#define STRTOD_NAN __wcstof_nan
|
||
+#include "../stdlib/strtod_nan_main.c"
|
||
Index: b/wcsmbs/wcstold_l.c
|
||
===================================================================
|
||
--- a/wcsmbs/wcstold_l.c
|
||
+++ b/wcsmbs/wcstold_l.c
|
||
@@ -24,8 +24,5 @@
|
||
|
||
extern long double ____wcstold_l_internal (const wchar_t *, wchar_t **, int,
|
||
__locale_t);
|
||
-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *,
|
||
- wchar_t **, int, int,
|
||
- __locale_t);
|
||
|
||
#include <strtold_l.c>
|
||
Index: b/wcsmbs/wcstold_nan.c
|
||
===================================================================
|
||
--- /dev/null
|
||
+++ b/wcsmbs/wcstold_nan.c
|
||
@@ -0,0 +1,30 @@
|
||
+/* Convert string for NaN payload to corresponding NaN. Wide strings,
|
||
+ long double.
|
||
+ Copyright (C) 2015 Free Software Foundation, Inc.
|
||
+ This file is part of the GNU C Library.
|
||
+
|
||
+ The GNU C Library is free software; you can redistribute it and/or
|
||
+ modify it under the terms of the GNU Lesser General Public
|
||
+ License as published by the Free Software Foundation; either
|
||
+ version 2.1 of the License, or (at your option) any later version.
|
||
+
|
||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
+ Lesser General Public License for more details.
|
||
+
|
||
+ You should have received a copy of the GNU Lesser General Public
|
||
+ License along with the GNU C Library; if not, see
|
||
+ <http://www.gnu.org/licenses/>. */
|
||
+
|
||
+#include <math.h>
|
||
+
|
||
+/* This function is unused if long double and double have the same
|
||
+ representation. */
|
||
+#ifndef __NO_LONG_DOUBLE_MATH
|
||
+# include "../stdlib/strtod_nan_wide.h"
|
||
+# include <strtod_nan_ldouble.h>
|
||
+
|
||
+# define STRTOD_NAN __wcstold_nan
|
||
+# include "../stdlib/strtod_nan_main.c"
|
||
+#endif
|