djdelorie / rpms / glibc

Forked from rpms/glibc 3 years ago
Clone
421842a
commit a7f0c5ae4184916f0e145de3aefc794bf2e280ad
421842a
Author: Joseph Myers <joseph@codesourcery.com>
421842a
Date:   Tue Nov 24 22:21:59 2015 +0000
421842a
421842a
    Fix strtod ("NAN(I)") in Turkish locales (bug 19266).
421842a
    
421842a
    The implementations of strtod and related functions use
421842a
    locale-specific conversions to lower case when parsing the contents of
421842a
    a string NAN(n-char-sequence_opt).  This has the consequence that
421842a
    NAN(I) is not treated as being of that form (only the initial NAN part
421842a
    is accepted).  The syntax of n-char-sequence directly maps to the
421842a
    ASCII letters, digits and underscore as in identifiers, so it is
421842a
    unambiguous that all ASCII letters must be accepted in all locales.
421842a
    
421842a
    This patch, relative to a tree with
421842a
    <https://sourceware.org/ml/libc-alpha/2015-11/msg00258.html> (pending
421842a
    review) applied and depending on that patch, fixes this problem by
421842a
    checking directly for ASCII letters.  This will have the side effect
421842a
    of no longer accepting 'İ' (dotted 'I') inside NAN() in Turkish
421842a
    locales, which seems appropriate (that letter wouldn't have been
421842a
    interpreted as having any meaning in the NaN payload anyway, as not
421842a
    acceptable to strtoull).
421842a
    
421842a
    Tested for x86_64 and x86.
421842a
    
421842a
    	[BZ #19266]
421842a
    	* stdlib/strtod_l.c (____STRTOF_INTERNAL): Check directly for
421842a
    	upper case and lower case letters inside NAN(), not using TOLOWER.
421842a
    	* stdlib/tst-strtod-nan-locale-main.c: New file.
421842a
    	* stdlib/tst-strtod-nan-locale.c: Likewise.
421842a
    	* stdlib/Makefile (tests): Add tst-strtod-nan-locale.
421842a
    	[$(run-built-tests) = yes] ($(objpfx)tst-strtod-nan-locale.out):
421842a
    	Depend on $(gen-locales).
421842a
    	($(objpfx)tst-strtod-nan-locale): Depend on $(libm).
421842a
    	* wcsmbs/tst-wcstod-nan-locale.c: New file.
421842a
    	* wcsmbs/Makefile (tests): Add tst-wcstod-nan-locale.
421842a
    	[$(run-built-tests) = yes] ($(objpfx)tst-wcstod-nan-locale.out):
421842a
    	Depend on $(gen-locales).
421842a
    	($(objpfx)tst-wcstod-nan-locale): Depend on $(libm).
421842a
421842a
Index: b/stdlib/Makefile
421842a
===================================================================
421842a
--- a/stdlib/Makefile
421842a
+++ b/stdlib/Makefile
421842a
@@ -75,7 +75,7 @@ tests		:= tst-strtol tst-strtod testmb t
421842a
 		   tst-secure-getenv tst-strtod-overflow tst-strtod-round   \
421842a
 		   tst-tininess tst-strtod-underflow tst-tls-atexit	    \
421842a
 		   tst-setcontext3 tst-tls-atexit-nodelete		    \
421842a
-		   tst-strtol-locale
421842a
+		   tst-strtol-locale tst-strtod-nan-locale
421842a
 tests-static	:= tst-secure-getenv
421842a
 
421842a
 modules-names	= tst-tls-atexit-lib
421842a
@@ -134,6 +134,7 @@ $(objpfx)tst-strtod3.out: $(gen-locales)
421842a
 $(objpfx)tst-strtod4.out: $(gen-locales)
421842a
 $(objpfx)tst-strtod5.out: $(gen-locales)
421842a
 $(objpfx)tst-strtol-locale.out: $(gen-locales)
421842a
+$(objpfx)tst-strtod-nan-locale.out: $(gen-locales)
421842a
 endif
421842a
 
421842a
 # Testdir has to be named stdlib and needs to be writable
421842a
@@ -168,6 +169,7 @@ $(objpfx)tst-strtod-round: $(libm)
421842a
 $(objpfx)tst-tininess: $(libm)
421842a
 $(objpfx)tst-strtod-underflow: $(libm)
421842a
 $(objpfx)tst-strtod6: $(libm)
421842a
+$(objpfx)tst-strtod-nan-locale: $(libm)
421842a
 
421842a
 tst-tls-atexit-lib.so-no-z-defs = yes
421842a
 
421842a
Index: b/stdlib/strtod_l.c
421842a
===================================================================
421842a
--- a/stdlib/strtod_l.c
421842a
+++ b/stdlib/strtod_l.c
421842a
@@ -658,8 +658,8 @@ ____STRTOF_INTERNAL (nptr, endptr, group
421842a
 	      do
421842a
 		++cp;
421842a
 	      while ((*cp >= L_('0') && *cp <= L_('9'))
421842a
-		     || ({ CHAR_TYPE lo = TOLOWER (*cp);
421842a
-			   lo >= L_('a') && lo <= L_('z'); })
421842a
+		     || (*cp >= L_('A') && *cp <= L_('Z'))
421842a
+		     || (*cp >= L_('a') && *cp <= L_('z'))
421842a
 		     || *cp == L_('_'));
421842a
 
421842a
 	      if (*cp != L_(')'))
421842a
Index: b/stdlib/tst-strtod-nan-locale-main.c
421842a
===================================================================
421842a
--- /dev/null
421842a
+++ b/stdlib/tst-strtod-nan-locale-main.c
421842a
@@ -0,0 +1,89 @@
421842a
+/* Test strtod functions work with all ASCII letters in NAN(...) in
421842a
+   Turkish locales (bug 19266).
421842a
+   Copyright (C) 2015 Free Software Foundation, Inc.
421842a
+   This file is part of the GNU C Library.
421842a
+
421842a
+   The GNU C Library is free software; you can redistribute it and/or
421842a
+   modify it under the terms of the GNU Lesser General Public
421842a
+   License as published by the Free Software Foundation; either
421842a
+   version 2.1 of the License, or (at your option) any later version.
421842a
+
421842a
+   The GNU C Library is distributed in the hope that it will be useful,
421842a
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
421842a
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
421842a
+   Lesser General Public License for more details.
421842a
+
421842a
+   You should have received a copy of the GNU Lesser General Public
421842a
+   License along with the GNU C Library; if not, see
421842a
+   <http://www.gnu.org/licenses/>.  */
421842a
+
421842a
+#include <locale.h>
421842a
+#include <math.h>
421842a
+#include <stdio.h>
421842a
+#include <stdlib.h>
421842a
+#include <wchar.h>
421842a
+
421842a
+#define STR_(X) #X
421842a
+#define STR(X) STR_(X)
421842a
+#define FNPFXS STR (FNPFX)
421842a
+#define CONCAT_(X, Y) X ## Y
421842a
+#define CONCAT(X, Y) CONCAT_ (X, Y)
421842a
+#define FNX(FN) CONCAT (FNPFX, FN)
421842a
+
421842a
+#define TEST(LOC, STR, FN, TYPE)					\
421842a
+  do									\
421842a
+    {									\
421842a
+      CHAR *ep;								\
421842a
+      TYPE val = FNX (FN) (STR, &ep);					\
421842a
+      if (isnan (val) && *ep == 0)					\
421842a
+	printf ("PASS: %s: " FNPFXS #FN " (" SFMT ")\n", LOC, STR);	\
421842a
+      else								\
421842a
+	{								\
421842a
+	  printf ("FAIL: %s: " FNPFXS #FN " (" SFMT ")\n", LOC, STR);	\
421842a
+	  result = 1;							\
421842a
+	}								\
421842a
+    }									\
421842a
+  while (0)
421842a
+
421842a
+static int
421842a
+test_one_locale (const char *loc)
421842a
+{
421842a
+  if (setlocale (LC_ALL, loc) == NULL)
421842a
+    {
421842a
+      printf ("setlocale (LC_ALL, \"%s\") failed\n", loc);
421842a
+      return 1;
421842a
+    }
421842a
+  int result = 0;
421842a
+  for (int i = 10; i < 36; i++)
421842a
+    {
421842a
+      CHAR s[7];
421842a
+      s[0] = L_('N');
421842a
+      s[1] = L_('A');
421842a
+      s[2] = L_('N');
421842a
+      s[3] = L_('(');
421842a
+      s[4] = L_('A') + i - 10;
421842a
+      s[5] = L_(')');
421842a
+      s[6] = 0;
421842a
+      TEST (loc, s, f, float);
421842a
+      TEST (loc, s, d, double);
421842a
+      TEST (loc, s, ld, long double);
421842a
+      s[4] = L_('a') + i - 10;
421842a
+      TEST (loc, s, f, float);
421842a
+      TEST (loc, s, d, double);
421842a
+      TEST (loc, s, ld, long double);
421842a
+    }
421842a
+  return result;
421842a
+}
421842a
+
421842a
+static int
421842a
+do_test (void)
421842a
+{
421842a
+  int result = 0;
421842a
+  result |= test_one_locale ("C");
421842a
+  result |= test_one_locale ("tr_TR.UTF-8");
421842a
+  result |= test_one_locale ("tr_TR.ISO-8859-9");
421842a
+  return result;
421842a
+}
421842a
+
421842a
+#define TEST_FUNCTION do_test ()
421842a
+#include "../test-skeleton.c"
421842a
Index: b/stdlib/tst-strtod-nan-locale.c
421842a
===================================================================
421842a
--- /dev/null
421842a
+++ b/stdlib/tst-strtod-nan-locale.c
421842a
@@ -0,0 +1,25 @@
421842a
+/* Test strtod functions work with all ASCII letters in NAN(...) in
421842a
+   Turkish locales (bug 19266).  Narrow string version.
421842a
+   Copyright (C) 2015 Free Software Foundation, Inc.
421842a
+   This file is part of the GNU C Library.
421842a
+
421842a
+   The GNU C Library is free software; you can redistribute it and/or
421842a
+   modify it under the terms of the GNU Lesser General Public
421842a
+   License as published by the Free Software Foundation; either
421842a
+   version 2.1 of the License, or (at your option) any later version.
421842a
+
421842a
+   The GNU C Library is distributed in the hope that it will be useful,
421842a
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
421842a
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
421842a
+   Lesser General Public License for more details.
421842a
+
421842a
+   You should have received a copy of the GNU Lesser General Public
421842a
+   License along with the GNU C Library; if not, see
421842a
+   <http://www.gnu.org/licenses/>.  */
421842a
+
421842a
+#define CHAR char
421842a
+#define SFMT "\"%s\""
421842a
+#define FNPFX strto
421842a
+#define L_(C) C
421842a
+
421842a
+#include <tst-strtod-nan-locale-main.c>
421842a
Index: b/wcsmbs/Makefile
421842a
===================================================================
421842a
--- a/wcsmbs/Makefile
421842a
+++ b/wcsmbs/Makefile
421842a
@@ -45,7 +45,7 @@ routines := wcscat wcschr wcscmp wcscpy
421842a
 strop-tests :=  wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy
421842a
 tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \
421842a
 	 tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \
421842a
-	 tst-c16c32-1 wcsatcliff tst-wcstol-locale \
421842a
+	 tst-c16c32-1 wcsatcliff tst-wcstol-locale tst-wcstod-nan-locale \
421842a
 	 $(addprefix test-,$(strop-tests))
421842a
 
421842a
 include ../Rules
421842a
@@ -62,6 +62,7 @@ $(objpfx)tst-mbrtowc2.out: $(gen-locales
421842a
 $(objpfx)tst-wcrtomb.out: $(gen-locales)
421842a
 $(objpfx)wcsmbs-tst1.out: $(gen-locales)
421842a
 $(objpfx)tst-wcstol-locale.out: $(gen-locales)
421842a
+$(objpfx)tst-wcstod-nan-locale.out: $(gen-locales)
421842a
 endif
421842a
 
421842a
 CFLAGS-wcwidth.c = -I../wctype
421842a
@@ -93,3 +94,5 @@ CPPFLAGS += $(libio-mtsafe)
421842a
 
421842a
 # We need to find the default version of strtold_l in stdlib.
421842a
 CPPFLAGS-wcstold_l.c = -I../stdlib
421842a
+
421842a
+$(objpfx)tst-wcstod-nan-locale: $(libm)
421842a
Index: b/wcsmbs/tst-wcstod-nan-locale.c
421842a
===================================================================
421842a
--- /dev/null
421842a
+++ b/wcsmbs/tst-wcstod-nan-locale.c
421842a
@@ -0,0 +1,25 @@
421842a
+/* Test strtod functions work with all ASCII letters in NAN(...) in
421842a
+   Turkish locales (bug 19266).  Wide string version.
421842a
+   Copyright (C) 2015 Free Software Foundation, Inc.
421842a
+   This file is part of the GNU C Library.
421842a
+
421842a
+   The GNU C Library is free software; you can redistribute it and/or
421842a
+   modify it under the terms of the GNU Lesser General Public
421842a
+   License as published by the Free Software Foundation; either
421842a
+   version 2.1 of the License, or (at your option) any later version.
421842a
+
421842a
+   The GNU C Library is distributed in the hope that it will be useful,
421842a
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
421842a
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
421842a
+   Lesser General Public License for more details.
421842a
+
421842a
+   You should have received a copy of the GNU Lesser General Public
421842a
+   License along with the GNU C Library; if not, see
421842a
+   <http://www.gnu.org/licenses/>.  */
421842a
+
421842a
+#define CHAR wchar_t
421842a
+#define SFMT "L\"%ls\""
421842a
+#define FNPFX wcsto
421842a
+#define L_(C) L ## C
421842a
+
421842a
+#include "../stdlib/tst-strtod-nan-locale-main.c"