From 0507ee3c5a1b13d6a0d44c3cbdf8d0ceac2fd250 Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Tue, 24 Nov 2015 10:07:51 +0100 Subject: [PATCH] glibc: add upstream patches Signed-off-by: Stephan Raue --- .../glibc/patches/glibc-99.01-BZ18921.patch | 27 ++ .../glibc/patches/glibc-99.02-BZ18887.patch | 206 +++++++++++ .../glibc/patches/glibc-99.03-BZ18781.patch | 71 ++++ .../glibc/patches/glibc-99.04-BZ18778.patch | 177 ++++++++++ .../glibc/patches/glibc-99.05-BZ18589.patch | 319 ++++++++++++++++++ 5 files changed, 800 insertions(+) create mode 100644 packages/devel/glibc/patches/glibc-99.01-BZ18921.patch create mode 100644 packages/devel/glibc/patches/glibc-99.02-BZ18887.patch create mode 100644 packages/devel/glibc/patches/glibc-99.03-BZ18781.patch create mode 100644 packages/devel/glibc/patches/glibc-99.04-BZ18778.patch create mode 100644 packages/devel/glibc/patches/glibc-99.05-BZ18589.patch diff --git a/packages/devel/glibc/patches/glibc-99.01-BZ18921.patch b/packages/devel/glibc/patches/glibc-99.01-BZ18921.patch new file mode 100644 index 0000000000..1211aaa32c --- /dev/null +++ b/packages/devel/glibc/patches/glibc-99.01-BZ18921.patch @@ -0,0 +1,27 @@ +From 5c8c3123652045191474a4ca85fbb6e8d9e7d2bc Mon Sep 17 00:00:00 2001 +From: Roland McGrath +Date: Fri, 4 Sep 2015 14:37:56 -0700 +Subject: [PATCH] BZ#18921: Fix opendir inverted o_directory_works test. + +(cherry picked from commit bd9e69abb887d78d0d6708fc089cc9f3eabf106d) +--- + ChangeLog | 8 ++++++++ + sysdeps/posix/opendir.c | 2 +- + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/sysdeps/posix/opendir.c b/sysdeps/posix/opendir.c +index 6509f5c..9edf056 100644 +--- a/sysdeps/posix/opendir.c ++++ b/sysdeps/posix/opendir.c +@@ -105,7 +105,7 @@ need_isdir_precheck (void) + tryopen_o_directory (); + + /* We can skip the expensive `stat' call if O_DIRECTORY works. */ +- return o_directory_works > 0; ++ return o_directory_works < 0; + #endif + return true; + } +-- +1.9.4 + diff --git a/packages/devel/glibc/patches/glibc-99.02-BZ18887.patch b/packages/devel/glibc/patches/glibc-99.02-BZ18887.patch new file mode 100644 index 0000000000..39becef717 --- /dev/null +++ b/packages/devel/glibc/patches/glibc-99.02-BZ18887.patch @@ -0,0 +1,206 @@ +From 3007f797a1a596e954f44879a5a7267966186ba4 Mon Sep 17 00:00:00 2001 +From: Mike Frysinger +Date: Fri, 28 Aug 2015 17:08:49 -0400 +Subject: [PATCH] getmntent: fix memory corruption w/blank lines [BZ #18887] + +The fix for BZ #17273 introduced a single byte of memory corruption when +the line is entirely blank. It would walk back past the start of the +buffer if the heap happened to be 0x20 or 0x09 and then write a NUL byte. + buffer = '\n'; + end_ptr = buffer; + while (end_ptr[-1] == ' ' || end_ptr[-1] == '\t') + end_ptr--; + *end_ptr = '\0'; + +Fix that and rework the tests. Adding the testcase for BZ #17273 to the +existing \040 parser does not really make sense as it's unrelated, and +leads to confusing behavior: it implicitly relies on the new entry being +longer than the previous entry (since it just rewinds the FILE*). Split +it out into its own dedicated testcase instead. + +(cherry picked from commit b0e805fa0d6fea33745952df7b7f5442ca4c374f) +--- + ChangeLog | 10 ++++++++ + NEWS | 2 +- + misc/Makefile | 3 ++- + misc/mntent_r.c | 4 +++- + misc/tst-mntent-blank-corrupt.c | 45 ++++++++++++++++++++++++++++++++++ + misc/tst-mntent-blank-passno.c | 53 +++++++++++++++++++++++++++++++++++++++++ + misc/tst-mntent.c | 20 ---------------- + 7 files changed, 114 insertions(+), 23 deletions(-) + create mode 100644 misc/tst-mntent-blank-corrupt.c + create mode 100644 misc/tst-mntent-blank-passno.c + +diff --git a/misc/Makefile b/misc/Makefile +index aecb0da..2f5edf6 100644 +--- a/misc/Makefile ++++ b/misc/Makefile +@@ -76,7 +76,8 @@ install-lib := libg.a + gpl2lgpl := error.c error.h + + tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \ +- tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1 ++ tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1 \ ++ tst-mntent-blank-corrupt tst-mntent-blank-passno + ifeq ($(run-built-tests),yes) + tests-special += $(objpfx)tst-error1-mem.out + endif +diff --git a/misc/mntent_r.c b/misc/mntent_r.c +index 6159873..4f26998 100644 +--- a/misc/mntent_r.c ++++ b/misc/mntent_r.c +@@ -136,7 +136,9 @@ __getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz) + end_ptr = strchr (buffer, '\n'); + if (end_ptr != NULL) /* chop newline */ + { +- while (end_ptr[-1] == ' ' || end_ptr[-1] == '\t') ++ /* Do not walk past the start of buffer if it's all whitespace. */ ++ while (end_ptr != buffer ++ && (end_ptr[-1] == ' ' || end_ptr[-1] == '\t')) + end_ptr--; + *end_ptr = '\0'; + } +diff --git a/misc/tst-mntent-blank-corrupt.c b/misc/tst-mntent-blank-corrupt.c +new file mode 100644 +index 0000000..92266a3 +--- /dev/null ++++ b/misc/tst-mntent-blank-corrupt.c +@@ -0,0 +1,45 @@ ++/* Make sure blank lines does not cause memory corruption BZ #18887. ++ ++ Copyright (C) 2009-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 ++ . */ ++ ++#include ++#include ++#include ++ ++/* Make sure blank lines don't trigger memory corruption. This doesn't happen ++ for all targets though, so it's a best effort test BZ #18887. */ ++static int ++do_test (void) ++{ ++ FILE *fp; ++ ++ fp = tmpfile (); ++ fputs ("\n \n/foo\\040dir /bar\\040dir auto bind \t \n", fp); ++ rewind (fp); ++ ++ /* The corruption happens here ... */ ++ getmntent (fp); ++ /* ... but trigers here. */ ++ endmntent (fp); ++ ++ /* If the test failed, we would crash, and not hit this point. */ ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/misc/tst-mntent-blank-passno.c b/misc/tst-mntent-blank-passno.c +new file mode 100644 +index 0000000..fc04291 +--- /dev/null ++++ b/misc/tst-mntent-blank-passno.c +@@ -0,0 +1,53 @@ ++/* Make sure trailing whitespace is handled properly BZ #17273. ++ ++ Copyright (C) 2009-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 ++ . */ ++ ++#include ++#include ++#include ++ ++/* Check entries to make sure trailing whitespace is ignored and we return the ++ correct passno value BZ #17273. */ ++static int ++do_test (void) ++{ ++ int result = 0; ++ FILE *fp; ++ struct mntent *mnt; ++ ++ fp = tmpfile (); ++ fputs ("/foo\\040dir /bar\\040dir auto bind \t \n", fp); ++ rewind (fp); ++ ++ mnt = getmntent (fp); ++ if (strcmp (mnt->mnt_fsname, "/foo dir") != 0 ++ || strcmp (mnt->mnt_dir, "/bar dir") != 0 ++ || strcmp (mnt->mnt_type, "auto") != 0 ++ || strcmp (mnt->mnt_opts, "bind") != 0 ++ || mnt->mnt_freq != 0 ++ || mnt->mnt_passno != 0) ++ { ++ puts ("Error while reading entry with trailing whitespaces"); ++ result = 1; ++ } ++ ++ return result; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/misc/tst-mntent.c b/misc/tst-mntent.c +index 876c89f..820b354 100644 +--- a/misc/tst-mntent.c ++++ b/misc/tst-mntent.c +@@ -73,26 +73,6 @@ main (int argc, char *argv[]) + puts ("Error while reading written entry back in"); + result = 1; + } +- +- /* Part III: Entry with whitespaces at the end of a line. */ +- rewind (fp); +- +- fputs ("/foo\\040dir /bar\\040dir auto bind \t \n", fp); +- +- rewind (fp); +- +- mnt = getmntent (fp); +- +- if (strcmp (mnt->mnt_fsname, "/foo dir") != 0 +- || strcmp (mnt->mnt_dir, "/bar dir") != 0 +- || strcmp (mnt->mnt_type, "auto") != 0 +- || strcmp (mnt->mnt_opts, "bind") != 0 +- || mnt->mnt_freq != 0 +- || mnt->mnt_passno != 0) +- { +- puts ("Error while reading entry with trailing whitespaces"); +- result = 1; +- } + } + + return result; +-- +1.9.4 + diff --git a/packages/devel/glibc/patches/glibc-99.03-BZ18781.patch b/packages/devel/glibc/patches/glibc-99.03-BZ18781.patch new file mode 100644 index 0000000000..0c1cf97acd --- /dev/null +++ b/packages/devel/glibc/patches/glibc-99.03-BZ18781.patch @@ -0,0 +1,71 @@ +From 561a9f11a974a447acb3dd03550a05df701a900e Mon Sep 17 00:00:00 2001 +From: Andreas Schwab +Date: Mon, 10 Aug 2015 14:12:47 +0200 +Subject: [PATCH] Readd O_LARGEFILE flag for openat64 (bug 18781) + +(cherry picked from commit eb32b0d40308166c4d8f6330cc2958cb1e545075) +--- + ChangeLog | 7 +++++++ + NEWS | 2 +- + io/test-lfs.c | 21 ++++++++++++++++++++- + sysdeps/unix/sysv/linux/openat.c | 5 +++++ + 4 files changed, 33 insertions(+), 2 deletions(-) + +diff --git a/io/test-lfs.c b/io/test-lfs.c +index 539c2a2..b6ebae4 100644 +--- a/io/test-lfs.c ++++ b/io/test-lfs.c +@@ -144,7 +144,7 @@ test_ftello (void) + int + do_test (int argc, char *argv[]) + { +- int ret; ++ int ret, fd2; + struct stat64 statbuf; + + ret = lseek64 (fd, TWO_GB+100, SEEK_SET); +@@ -195,6 +195,25 @@ do_test (int argc, char *argv[]) + error (EXIT_FAILURE, 0, "stat reported size %lld instead of %lld.", + (long long int) statbuf.st_size, (TWO_GB + 100 + 5)); + ++ fd2 = openat64 (AT_FDCWD, name, O_RDWR); ++ if (fd2 == -1) ++ { ++ if (errno == ENOSYS) ++ { ++ /* Silently ignore this test. */ ++ error (0, 0, "openat64 is not supported"); ++ } ++ else ++ error (EXIT_FAILURE, errno, "openat64 failed to open big file"); ++ } ++ else ++ { ++ ret = close (fd2); ++ ++ if (ret == -1) ++ error (EXIT_FAILURE, errno, "error closing file"); ++ } ++ + test_ftello (); + + return 0; +diff --git a/sysdeps/unix/sysv/linux/openat.c b/sysdeps/unix/sysv/linux/openat.c +index 6777123..ad8e31d 100644 +--- a/sysdeps/unix/sysv/linux/openat.c ++++ b/sysdeps/unix/sysv/linux/openat.c +@@ -68,6 +68,11 @@ __OPENAT (int fd, const char *file, int oflag, ...) + va_end (arg); + } + ++ /* We have to add the O_LARGEFILE flag for openat64. */ ++#ifdef MORE_OFLAGS ++ oflag |= MORE_OFLAGS; ++#endif ++ + return SYSCALL_CANCEL (openat, fd, file, oflag, mode); + } + libc_hidden_def (__OPENAT) +-- +1.9.4 + diff --git a/packages/devel/glibc/patches/glibc-99.04-BZ18778.patch b/packages/devel/glibc/patches/glibc-99.04-BZ18778.patch new file mode 100644 index 0000000000..1d1998c09d --- /dev/null +++ b/packages/devel/glibc/patches/glibc-99.04-BZ18778.patch @@ -0,0 +1,177 @@ +From a34d1c6afc86521d6ad17662a3b5362d8481514c Mon Sep 17 00:00:00 2001 +From: Maxim Ostapenko +Date: Mon, 10 Aug 2015 10:47:54 +0300 +Subject: [PATCH] Clear DF_1_NODELETE flag only for failed to load library. + +https://sourceware.org/bugzilla/show_bug.cgi?id=18778 + +If dlopen fails to load an object that has triggered loading libpthread it +causes ld.so to unload libpthread because its DF_1_NODELETE flags has been +forcefully cleared. The next call to __rtdl_unlock_lock_recursive will crash +since pthread_mutex_unlock no longer exists. + +This patch moves l->l_flags_1 &= ~DF_1_NODELETE out of loop through all loaded +libraries and performs the action only on inconsistent one. + + [BZ #18778] + * elf/Makefile (tests): Add Add tst-nodelete2. + (modules-names): Add tst-nodelete2mod. + (tst-nodelete2mod.so-no-z-defs): New. + ($(objpfx)tst-nodelete2): Likewise. + ($(objpfx)tst-nodelete2.out): Likewise. + (LDFLAGS-tst-nodelete2): Likewise. + * elf/dl-close.c (_dl_close_worker): Move DF_1_NODELETE clearing + out of loop through all loaded libraries. + * elf/tst-nodelete2.c: New file. + * elf/tst-nodelete2mod.c: Likewise. + +(cherry picked from commit f25238ffe0455013174438376b3ee88df496f9d1) +--- + ChangeLog | 14 +++++++++ + NEWS | 2 +- + elf/Makefile | 11 +++++-- + elf/dl-close.c | 15 ++++----- + elf/tst-nodelete2.c | 37 +++++++++++++++++++++++ + elf/{tst-znodelete-zlib.cc => tst-nodelete2mod.c} | 3 +- + 6 files changed, 71 insertions(+), 11 deletions(-) + create mode 100644 elf/tst-nodelete2.c + rename elf/{tst-znodelete-zlib.cc => tst-nodelete2mod.c} (50%) + +diff --git a/elf/Makefile b/elf/Makefile +index 4ceeaf8..71a18a1 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -148,7 +148,8 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \ + tst-unique1 tst-unique2 $(if $(CXX),tst-unique3 tst-unique4 \ + tst-nodelete) \ + tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \ +- tst-ptrguard1 tst-tlsalign tst-tlsalign-extern tst-nodelete-opened ++ tst-ptrguard1 tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \ ++ tst-nodelete2 + # reldep9 + ifeq ($(build-hardcoded-path-in-tests),yes) + tests += tst-dlopen-aout +@@ -218,7 +219,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ + tst-initorder2d \ + tst-relsort1mod1 tst-relsort1mod2 tst-array2dep \ + tst-array5dep tst-null-argv-lib \ +- tst-tlsalign-lib tst-nodelete-opened-lib ++ tst-tlsalign-lib tst-nodelete-opened-lib tst-nodelete2mod + ifeq (yes,$(have-protected-data)) + modules-names += tst-protected1moda tst-protected1modb + tests += tst-protected1a tst-protected1b +@@ -594,6 +595,7 @@ tst-auditmod9b.so-no-z-defs = yes + tst-nodelete-uniquemod.so-no-z-defs = yes + tst-nodelete-rtldmod.so-no-z-defs = yes + tst-nodelete-zmod.so-no-z-defs = yes ++tst-nodelete2mod.so-no-z-defs = yes + + ifeq ($(build-shared),yes) + # Build all the modules even when not actually running test programs. +@@ -1164,6 +1166,11 @@ $(objpfx)tst-nodelete.out: $(objpfx)tst-nodelete-uniquemod.so \ + LDFLAGS-tst-nodelete = -rdynamic + LDFLAGS-tst-nodelete-zmod.so = -Wl,--enable-new-dtags,-z,nodelete + ++$(objpfx)tst-nodelete2: $(libdl) ++$(objpfx)tst-nodelete2.out: $(objpfx)tst-nodelete2mod.so ++ ++LDFLAGS-tst-nodelete2 = -rdynamic ++ + $(objpfx)tst-initorder-cmp.out: tst-initorder.exp $(objpfx)tst-initorder.out + cmp $^ > $@; \ + $(evaluate-test) +diff --git a/elf/dl-close.c b/elf/dl-close.c +index 9105277..c897247 100644 +--- a/elf/dl-close.c ++++ b/elf/dl-close.c +@@ -144,6 +144,14 @@ _dl_close_worker (struct link_map *map, bool force) + char done[nloaded]; + struct link_map *maps[nloaded]; + ++ /* Clear DF_1_NODELETE to force object deletion. We don't need to touch ++ l_tls_dtor_count because forced object deletion only happens when an ++ error occurs during object load. Destructor registration for TLS ++ non-POD objects should not have happened till then for this ++ object. */ ++ if (force) ++ map->l_flags_1 &= ~DF_1_NODELETE; ++ + /* Run over the list and assign indexes to the link maps and enter + them into the MAPS array. */ + int idx = 0; +@@ -153,13 +161,6 @@ _dl_close_worker (struct link_map *map, bool force) + maps[idx] = l; + ++idx; + +- /* Clear DF_1_NODELETE to force object deletion. We don't need to touch +- l_tls_dtor_count because forced object deletion only happens when an +- error occurs during object load. Destructor registration for TLS +- non-POD objects should not have happened till then for this +- object. */ +- if (force) +- l->l_flags_1 &= ~DF_1_NODELETE; + } + assert (idx == nloaded); + +diff --git a/elf/tst-nodelete2.c b/elf/tst-nodelete2.c +new file mode 100644 +index 0000000..388e8af +--- /dev/null ++++ b/elf/tst-nodelete2.c +@@ -0,0 +1,37 @@ ++#include "../dlfcn/dlfcn.h" ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ int result = 0; ++ ++ printf ("\nOpening pthread library.\n"); ++ void *pthread = dlopen (LIBPTHREAD_SO, RTLD_LAZY); ++ ++ /* This is a test for correct DF_1_NODELETE clearing when dlopen failure ++ happens. We should clear DF_1_NODELETE for failed library only, because ++ doing this for others (e.g. libpthread) might cause them to be unloaded, ++ that may lead to some global references (e.g. __rtld_lock_unlock) to be ++ broken. The dlopen should fail because of undefined symbols in shared ++ library, that cause DF_1_NODELETE to be cleared. For libpthread, this ++ flag should be set, because if not, SIGSEGV will happen in dlclose. */ ++ if (dlopen ("tst-nodelete2mod.so", RTLD_NOW) != NULL) ++ { ++ printf ("Unique symbols test failed\n"); ++ result = 1; ++ } ++ ++ if (pthread) ++ dlclose (pthread); ++ ++ if (result == 0) ++ printf ("SUCCESS\n"); ++ ++ return result; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/elf/tst-znodelete-zlib.cc b/elf/tst-nodelete2mod.c +similarity index 50% +rename from elf/tst-znodelete-zlib.cc +rename to elf/tst-nodelete2mod.c +index 1e8f368..e88c756 100644 +--- a/elf/tst-znodelete-zlib.cc ++++ b/elf/tst-nodelete2mod.c +@@ -1,6 +1,7 @@ ++/* Undefined symbol. */ + extern int not_exist (void); + + int foo (void) + { +- return not_exist (); ++ return not_exist (); + } +-- +1.9.4 + diff --git a/packages/devel/glibc/patches/glibc-99.05-BZ18589.patch b/packages/devel/glibc/patches/glibc-99.05-BZ18589.patch new file mode 100644 index 0000000000..dc88acb90b --- /dev/null +++ b/packages/devel/glibc/patches/glibc-99.05-BZ18589.patch @@ -0,0 +1,319 @@ +From 6c84109cfa26f35c3dfed3acb97d347361bd5849 Mon Sep 17 00:00:00 2001 +From: Carlos O'Donell +Date: Thu, 8 Oct 2015 16:34:53 -0400 +Subject: [PATCH] strcoll: Remove incorrect STRDIFF-based optimization (Bug + 18589). + +The optimization introduced in commit +f13c2a8dff2329c6692a80176262ceaaf8a6f74e, causes regressions in +sorting for languages that have digraphs that change sort order, like +cs_CZ which sorts ch between h and i. + +My analysis shows the fast-forwarding optimization in STRCOLL advances +through a digraph while possibly stopping in the middle which results +in a subsequent skipping of the digraph and incorrect sorting. The +optimization is incorrect as implemented and because of that I'm +removing it for 2.23, and I will also commit this fix for 2.22 where +it was originally introduced. + +This patch reverts the optimization, introduces a new bug-strcoll2.c +regression test that tests both cs_CZ.UTF-8 and da_DK.ISO-8859-1 and +ensures they sort one digraph each correctly. The optimization can't be +applied without regressing this test. + +Checked on x86_64, bug-strcoll2.c fails without this patch and passes +after. This will also get a fix on 2.22 which has the same bug. + +(cherry picked from commit 87701a58e291bd7ac3b407d10a829dac52c9c16e) +--- + ChangeLog | 14 +++++++ + NEWS | 2 +- + locale/C-collate.c | 4 +- + locale/categories.def | 1 - + locale/langinfo.h | 1 - + locale/localeinfo.h | 8 ---- + locale/programs/ld-collate.c | 9 ----- + string/bug-strcoll2.c | 93 ++++++++++++++++++++++++++++++++++++++++++++ + string/strcoll_l.c | 38 +----------------- + wcsmbs/wcscoll_l.c | 1 - + 10 files changed, 110 insertions(+), 61 deletions(-) + create mode 100644 string/bug-strcoll2.c + +diff --git a/locale/C-collate.c b/locale/C-collate.c +index d7f3c55..06dfdfa 100644 +--- a/locale/C-collate.c ++++ b/locale/C-collate.c +@@ -144,8 +144,6 @@ const struct __locale_data _nl_C_LC_COLLATE attribute_hidden = + /* _NL_COLLATE_COLLSEQWC */ + { .string = (const char *) collseqwc }, + /* _NL_COLLATE_CODESET */ +- { .string = _nl_C_codeset }, +- /* _NL_COLLATE_ENCODING_TYPE */ +- { .word = __cet_8bit } ++ { .string = _nl_C_codeset } + } + }; +diff --git a/locale/categories.def b/locale/categories.def +index 045489d..a8dda53 100644 +--- a/locale/categories.def ++++ b/locale/categories.def +@@ -58,7 +58,6 @@ DEFINE_CATEGORY + DEFINE_ELEMENT (_NL_COLLATE_COLLSEQMB, "collate-collseqmb", std, wstring) + DEFINE_ELEMENT (_NL_COLLATE_COLLSEQWC, "collate-collseqwc", std, wstring) + DEFINE_ELEMENT (_NL_COLLATE_CODESET, "collate-codeset", std, string) +- DEFINE_ELEMENT (_NL_COLLATE_ENCODING_TYPE, "collate-encoding-type", std, word) + ), NO_POSTLOAD) + + +diff --git a/locale/langinfo.h b/locale/langinfo.h +index ffc5c7f..a565d9d 100644 +--- a/locale/langinfo.h ++++ b/locale/langinfo.h +@@ -255,7 +255,6 @@ enum + _NL_COLLATE_COLLSEQMB, + _NL_COLLATE_COLLSEQWC, + _NL_COLLATE_CODESET, +- _NL_COLLATE_ENCODING_TYPE, + _NL_NUM_LC_COLLATE, + + /* LC_CTYPE category: character classification. +diff --git a/locale/localeinfo.h b/locale/localeinfo.h +index bdab9fe..1d2ee00 100644 +--- a/locale/localeinfo.h ++++ b/locale/localeinfo.h +@@ -110,14 +110,6 @@ enum coll_sort_rule + sort_mask + }; + +-/* Collation encoding type. */ +-enum collation_encoding_type +-{ +- __cet_other, +- __cet_8bit, +- __cet_utf8 +-}; +- + /* We can map the types of the entries into a few categories. */ + enum value_type + { +diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c +index a39a94f..dc0fe30 100644 +--- a/locale/programs/ld-collate.c ++++ b/locale/programs/ld-collate.c +@@ -32,7 +32,6 @@ + #include "linereader.h" + #include "locfile.h" + #include "elem-hash.h" +-#include "../localeinfo.h" + + /* Uncomment the following line in the production version. */ + /* #define NDEBUG 1 */ +@@ -2131,8 +2130,6 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, + /* The words have to be handled specially. */ + if (idx == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZEMB)) + add_locale_uint32 (&file, 0); +- else if (idx == _NL_ITEM_INDEX (_NL_COLLATE_ENCODING_TYPE)) +- add_locale_uint32 (&file, __cet_other); + else + add_locale_empty (&file); + } +@@ -2496,12 +2493,6 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, + add_locale_raw_data (&file, collate->mbseqorder, 256); + add_locale_collseq_table (&file, &collate->wcseqorder); + add_locale_string (&file, charmap->code_set_name); +- if (strcmp (charmap->code_set_name, "UTF-8") == 0) +- add_locale_uint32 (&file, __cet_utf8); +- else if (charmap->mb_cur_max == 1) +- add_locale_uint32 (&file, __cet_8bit); +- else +- add_locale_uint32 (&file, __cet_other); + write_locale_data (output_path, LC_COLLATE, "LC_COLLATE", &file); + + obstack_free (&weightpool, NULL); +diff --git a/string/bug-strcoll2.c b/string/bug-strcoll2.c +new file mode 100644 +index 0000000..5ce2f94 +--- /dev/null ++++ b/string/bug-strcoll2.c +@@ -0,0 +1,93 @@ ++/* Bug 18589: sort-test.sh fails at random. ++ Copyright (C) 1998-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Ulrich Drepper , 1998. ++ ++ 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 ++ . */ ++ ++#include ++#include ++#include ++ ++/* An incorrect strcoll optimization resulted in incorrect ++ results from strcoll for cs_CZ and da_DK. */ ++ ++int ++test_cs_CZ (void) ++{ ++ const char t1[] = "config"; ++ const char t2[] = "choose"; ++ if (setlocale (LC_ALL, "cs_CZ.UTF-8") == NULL) ++ { ++ perror ("setlocale"); ++ return 1; ++ } ++ /* In Czech the digraph ch sorts after c, therefore we expect ++ config to sort before choose. */ ++ int a = strcoll (t1, t2); ++ int b = strcoll (t2, t1); ++ printf ("strcoll (\"%s\", \"%s\") = %d\n", t1, t2, a); ++ printf ("strcoll (\"%s\", \"%s\") = %d\n", t2, t1, b); ++ if (a < 0 && b > 0) ++ { ++ puts ("PASS: config < choose"); ++ return 0; ++ } ++ else ++ { ++ puts ("FAIL: Wrong sorting in cz_CZ.UTF-8."); ++ return 1; ++ } ++} ++ ++int ++test_da_DK (void) ++{ ++ const char t1[] = "AS"; ++ const char t2[] = "AA"; ++ if (setlocale (LC_ALL, "da_DK.ISO-8859-1") == NULL) ++ { ++ perror ("setlocale"); ++ return 1; ++ } ++ /* AA should be treated as the last letter of the Danish alphabet, ++ hence sorting after AS. */ ++ int a = strcoll (t1, t2); ++ int b = strcoll (t2, t1); ++ printf ("strcoll (\"%s\", \"%s\") = %d\n", t1, t2, a); ++ printf ("strcoll (\"%s\", \"%s\") = %d\n", t2, t1, b); ++ if (a < 0 && b > 0) ++ { ++ puts ("PASS: AS < AA"); ++ return 0; ++ } ++ else ++ { ++ puts ("FAIL: Wrong sorting in da_DK.ISO-8859-1"); ++ return 1; ++ } ++} ++ ++static int ++do_test (void) ++{ ++ int err = 0; ++ err |= test_cs_CZ (); ++ err |= test_da_DK (); ++ return err; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/string/strcoll_l.c b/string/strcoll_l.c +index 8f1225f..35bc0e4 100644 +--- a/string/strcoll_l.c ++++ b/string/strcoll_l.c +@@ -29,7 +29,6 @@ + # define STRING_TYPE char + # define USTRING_TYPE unsigned char + # define STRCOLL __strcoll_l +-# define STRDIFF __strdiff + # define STRCMP strcmp + # define WEIGHT_H "../locale/weight.h" + # define SUFFIX MB +@@ -42,20 +41,6 @@ + #include "../locale/localeinfo.h" + #include WEIGHT_H + +-#define MASK_UTF8_7BIT (1 << 7) +-#define MASK_UTF8_START (3 << 6) +- +-size_t +-STRDIFF (const STRING_TYPE *s, const STRING_TYPE *t) +-{ +- size_t n; +- +- for (n = 0; *s != '\0' && *s++ == *t++; ++n) +- continue; +- +- return n; +-} +- + /* Track status while looking for sequences in a string. */ + typedef struct + { +@@ -269,29 +254,9 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l) + const USTRING_TYPE *extra; + const int32_t *indirect; + +- /* In case there is no locale specific sort order (C / POSIX). */ + if (nrules == 0) + return STRCMP (s1, s2); + +- /* Fast forward to the position of the first difference. Needs to be +- encoding aware as the byte-by-byte comparison can stop in the middle +- of a char sequence for multibyte encodings like UTF-8. */ +- uint_fast32_t encoding = +- current->values[_NL_ITEM_INDEX (_NL_COLLATE_ENCODING_TYPE)].word; +- if (encoding != __cet_other) +- { +- size_t diff = STRDIFF (s1, s2); +- if (diff > 0) +- { +- if (encoding == __cet_utf8 && (*(s1 + diff) & MASK_UTF8_7BIT) != 0) +- do +- diff--; +- while (diff > 0 && (*(s1 + diff) & MASK_UTF8_START) != MASK_UTF8_START); +- s1 += diff; +- s2 += diff; +- } +- } +- + /* Catch empty strings. */ + if (__glibc_unlikely (*s1 == '\0') || __glibc_unlikely (*s2 == '\0')) + return (*s1 != '\0') - (*s2 != '\0'); +@@ -358,8 +323,7 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l) + byte-level comparison to ensure that we don't waste time + going through multiple passes for totally equal strings + before proceeding to subsequent passes. */ +- if (pass == 0 && encoding == __cet_other && +- STRCMP (s1, s2) == 0) ++ if (pass == 0 && STRCMP (s1, s2) == 0) + return result; + else + break; +diff --git a/wcsmbs/wcscoll_l.c b/wcsmbs/wcscoll_l.c +index 6d9384a..87f240d 100644 +--- a/wcsmbs/wcscoll_l.c ++++ b/wcsmbs/wcscoll_l.c +@@ -23,7 +23,6 @@ + #define STRING_TYPE wchar_t + #define USTRING_TYPE wint_t + #define STRCOLL __wcscoll_l +-#define STRDIFF __wcsdiff + #define STRCMP __wcscmp + #define WEIGHT_H "../locale/weightwc.h" + #define SUFFIX WC +-- +1.9.4 +