djdelorie / rpms / glibc

Forked from rpms/glibc 3 years ago
Clone
421842a
commit f5eee5c72b2ab56f3faf4f46729fe82805efde68
421842a
Author: Joseph Myers <joseph@codesourcery.com>
421842a
Date:   Mon Nov 23 08:50:53 2015 +0000
421842a
421842a
    Fix strtol in Turkish locales (bug 19242).
421842a
    
421842a
    The implementations of strtol and related functions use
421842a
    locale-specific conversions to upper case before determining whether a
421842a
    character is a valid letter in the argument.  This means that in
421842a
    Turkish locales such as tr_TR.UTF-8 and tr_TR.ISO-8859-9, "i" is
421842a
    interpreted as not being a valid number, when if the base passed to
421842a
    strtol is 19 or more it should be interpreted as the number 18.
421842a
    
421842a
    ISO C explicitly says "The letters from a (or A) through z (or Z) are
421842a
    ascribed the values 10 through 35", so clearly intends the standard
421842a
    ASCII letters (otherwise you wouldn't generally have exactly 26
421842a
    letters to ascribe such values) (whereas white-space must be
421842a
    identified according to the locale).  In particular, 'i' and 'I' must
421842a
    be understood to be in that sequence.
421842a
    
421842a
    This patch makes the code do the case conversions and classification
421842a
    in the C locale; the user's locale remains used for whitespace testing
421842a
    (explicitly correct according to ISO C).  Note that the way the code
421842a
    worked, the only non-ASCII letter that would previously have been
421842a
    accepted would have been the Turkish 'ı' (dotless 'i'), because the
421842a
    uppercase version of that in Turkish locales is 'I'.  This patch means
421842a
    that will no longer be accepted, which seems appropriate.
421842a
    
421842a
    Tested for x86_64 and x86.
421842a
    
421842a
    	[BZ #19242]
421842a
    	* stdlib/strtol_l.c (ISALPHA): Use _nl_C_locobj_ptr for locale.
421842a
    	(TOUPPER): Likewise.
421842a
    	* stdlib/tst-strtol-locale-main.c: New file.
421842a
    	* stdlib/tst-strtol-locale.c: Likewise.
421842a
    	* stdlib/Makefile (tests): Add tst-strtol-locale.
421842a
    	[$(run-built-tests) = yes] (LOCALES): Add tr_TR.ISO-8859-9.
421842a
    	[$(run-built-tests) = yes] ($(objpfx)tst-strtol-locale.out):
421842a
    	Depend on $(gen-locales).
421842a
    	* wcsmbs/tst-wcstol-locale.c: New file.
421842a
    	* wcsmbs/Makefile (tests): Add tst-wcstol-locale.
421842a
    	[$(run-built-tests) = yes] (LOCALES): Add tr_TR.UTF-8 and
421842a
    	tr_TR.ISO-8859-9.
421842a
    	[$(run-built-tests) = yes] ($(objpfx)tst-wcstol-locale.out):
421842a
    	Depend on $(gen-locales).
421842a
421842a
Index: b/stdlib/Makefile
421842a
===================================================================
421842a
--- a/stdlib/Makefile
421842a
+++ b/stdlib/Makefile
421842a
@@ -74,7 +74,8 @@ tests		:= tst-strtol tst-strtod testmb t
421842a
 		   tst-makecontext3 bug-getcontext bug-fmtmsg1		    \
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-setcontext3 tst-tls-atexit-nodelete		    \
421842a
+		   tst-strtol-locale
421842a
 tests-static	:= tst-secure-getenv
421842a
 
421842a
 modules-names	= tst-tls-atexit-lib
421842a
@@ -122,7 +123,8 @@ endif
421842a
 include ../Rules
421842a
 
421842a
 ifeq ($(run-built-tests),yes)
421842a
-LOCALES := cs_CZ.UTF-8 de_DE.UTF-8 en_US.ISO-8859-1 tr_TR.UTF-8
421842a
+LOCALES := cs_CZ.UTF-8 de_DE.UTF-8 en_US.ISO-8859-1 tr_TR.UTF-8 \
421842a
+	   tr_TR.ISO-8859-9
421842a
 include ../gen-locales.mk
421842a
 
421842a
 $(objpfx)bug-strtod2.out: $(gen-locales)
421842a
@@ -131,6 +133,7 @@ $(objpfx)tst-strtod.out: $(gen-locales)
421842a
 $(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
 endif
421842a
 
421842a
 # Testdir has to be named stdlib and needs to be writable
421842a
Index: b/stdlib/strtol_l.c
421842a
===================================================================
421842a
--- a/stdlib/strtol_l.c
421842a
+++ b/stdlib/strtol_l.c
421842a
@@ -137,8 +137,8 @@
421842a
 # define UCHAR_TYPE wint_t
421842a
 # define STRING_TYPE wchar_t
421842a
 # define ISSPACE(Ch) __iswspace_l ((Ch), loc)
421842a
-# define ISALPHA(Ch) __iswalpha_l ((Ch), loc)
421842a
-# define TOUPPER(Ch) __towupper_l ((Ch), loc)
421842a
+# define ISALPHA(Ch) __iswalpha_l ((Ch), _nl_C_locobj_ptr)
421842a
+# define TOUPPER(Ch) __towupper_l ((Ch), _nl_C_locobj_ptr)
421842a
 #else
421842a
 # if defined _LIBC \
421842a
    || defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII)
421842a
@@ -150,8 +150,8 @@
421842a
 # define UCHAR_TYPE unsigned char
421842a
 # define STRING_TYPE char
421842a
 # define ISSPACE(Ch) __isspace_l ((Ch), loc)
421842a
-# define ISALPHA(Ch) __isalpha_l ((Ch), loc)
421842a
-# define TOUPPER(Ch) __toupper_l ((Ch), loc)
421842a
+# define ISALPHA(Ch) __isalpha_l ((Ch), _nl_C_locobj_ptr)
421842a
+# define TOUPPER(Ch) __toupper_l ((Ch), _nl_C_locobj_ptr)
421842a
 #endif
421842a
 
421842a
 #define INTERNAL(X) INTERNAL1(X)
421842a
Index: b/stdlib/tst-strtol-locale-main.c
421842a
===================================================================
421842a
--- /dev/null
421842a
+++ b/stdlib/tst-strtol-locale-main.c
421842a
@@ -0,0 +1,87 @@
421842a
+/* Test strtol functions work with all ASCII letters in Turkish
421842a
+   locales (bug 19242).
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 <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, EXP_VAL, FN, TYPE, FMT)				\
421842a
+  do									\
421842a
+    {									\
421842a
+      CHAR *ep;								\
421842a
+      TYPE val = FNX (FN) (STR, &ep, 36);				\
421842a
+      printf ("%s: " FNPFXS #FN " (" SFMT ") == " FMT "\n", LOC, STR, val); \
421842a
+      if (val == (TYPE) (EXP_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[2];
421842a
+      s[0] = L_('A') + i - 10;
421842a
+      s[1] = 0;
421842a
+      TEST (loc, s, i, l, long int, "%ld");
421842a
+      TEST (loc, s, i, ul, unsigned long int, "%lu");
421842a
+      TEST (loc, s, i, ll, long long int, "%lld");
421842a
+      TEST (loc, s, i, ull, unsigned long long int, "%llu");
421842a
+      s[0] = L_('a') + i - 10;
421842a
+      s[1] = 0;
421842a
+      TEST (loc, s, i, l, long int, "%ld");
421842a
+      TEST (loc, s, i, ul, unsigned long int, "%lu");
421842a
+      TEST (loc, s, i, ll, long long int, "%lld");
421842a
+      TEST (loc, s, i, ull, unsigned long long int, "%llu");
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-strtol-locale.c
421842a
===================================================================
421842a
--- /dev/null
421842a
+++ b/stdlib/tst-strtol-locale.c
421842a
@@ -0,0 +1,25 @@
421842a
+/* Test strtol functions work with all ASCII letters in Turkish
421842a
+   locales (bug 19242).  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-strtol-locale-main.c>
421842a
Index: b/wcsmbs/Makefile
421842a
===================================================================
421842a
--- a/wcsmbs/Makefile
421842a
+++ b/wcsmbs/Makefile
421842a
@@ -45,13 +45,14 @@ 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 $(addprefix test-,$(strop-tests))
421842a
+	 tst-c16c32-1 wcsatcliff tst-wcstol-locale \
421842a
+	 $(addprefix test-,$(strop-tests))
421842a
 
421842a
 include ../Rules
421842a
 
421842a
 ifeq ($(run-built-tests),yes)
421842a
 LOCALES := de_DE.ISO-8859-1 de_DE.UTF-8 en_US.ANSI_X3.4-1968 hr_HR.ISO-8859-2 \
421842a
-	   ja_JP.EUC-JP zh_TW.EUC-TW
421842a
+	   ja_JP.EUC-JP zh_TW.EUC-TW tr_TR.UTF-8 tr_TR.ISO-8859-9
421842a
 include ../gen-locales.mk
421842a
 
421842a
 $(objpfx)tst-btowc.out: $(gen-locales)
421842a
@@ -60,6 +61,7 @@ $(objpfx)tst-mbrtowc.out: $(gen-locales)
421842a
 $(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
 endif
421842a
 
421842a
 CFLAGS-wcwidth.c = -I../wctype
421842a
Index: b/wcsmbs/tst-wcstol-locale.c
421842a
===================================================================
421842a
--- /dev/null
421842a
+++ b/wcsmbs/tst-wcstol-locale.c
421842a
@@ -0,0 +1,25 @@
421842a
+/* Test strtol functions work with all ASCII letters in Turkish
421842a
+   locales (bug 19242).  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-strtol-locale-main.c"