Merge pull request #4723 from MilhouseVH/glibc_exploit

[glibc] Bump to 2.23 fixing CVE-2015-7547
This commit is contained in:
Stephan Raue 2016-02-19 12:31:33 +01:00
commit ee340f7398
6 changed files with 1 additions and 801 deletions

View File

@ -17,7 +17,7 @@
################################################################################
PKG_NAME="glibc"
PKG_VERSION="2.22"
PKG_VERSION="2.23"
PKG_REV="1"
PKG_ARCH="any"
PKG_LICENSE="GPL"

View File

@ -1,27 +0,0 @@
From 5c8c3123652045191474a4ca85fbb6e8d9e7d2bc Mon Sep 17 00:00:00 2001
From: Roland McGrath <roland@hack.frob.com>
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

View File

@ -1,206 +0,0 @@
From 3007f797a1a596e954f44879a5a7267966186ba4 Mon Sep 17 00:00:00 2001
From: Mike Frysinger <vapier@gentoo.org>
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
+ <http://www.gnu.org/licenses/>. */
+
+#include <mntent.h>
+#include <stdio.h>
+#include <string.h>
+
+/* 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <mntent.h>
+#include <stdio.h>
+#include <string.h>
+
+/* 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

View File

@ -1,71 +0,0 @@
From 561a9f11a974a447acb3dd03550a05df701a900e Mon Sep 17 00:00:00 2001
From: Andreas Schwab <schwab@suse.de>
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

View File

@ -1,177 +0,0 @@
From a34d1c6afc86521d6ad17662a3b5362d8481514c Mon Sep 17 00:00:00 2001
From: Maxim Ostapenko <m.ostapenko@partner.samsung.com>
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 <stdio.h>
+#include <stdlib.h>
+#include <gnu/lib-names.h>
+
+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

View File

@ -1,319 +0,0 @@
From 6c84109cfa26f35c3dfed3acb97d347361bd5849 Mon Sep 17 00:00:00 2001
From: Carlos O'Donell <carlos@systemhalted.org>
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 <drepper@cygnus.com>, 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <string.h>
+#include <locale.h>
+
+/* 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