forked from lattera/glibc
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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.
- Loading branch information
Showing
28 changed files
with
504 additions
and
95 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,54 @@ | ||
2015-11-24 Joseph Myers <[email protected]> | ||
|
||
* 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. | ||
|
||
[BZ #19266] | ||
* stdlib/strtod_l.c (____STRTOF_INTERNAL): Check directly for | ||
upper case and lower case letters inside NAN(), not using TOLOWER. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
Oops, something went wrong.