forked from pool/glibc
Andreas Schwab
9627e11e8b
- Update to glibc 2.25 * The feature test macro __STDC_WANT_LIB_EXT2__, from ISO/IEC TR 24731-2:2010, is supported to enable declarations of functions from that TR. * The feature test macro __STDC_WANT_IEC_60559_BFP_EXT__, from ISO/IEC TS 18661-1:2014, is supported to enable declarations of functions and macros from that TS. * The feature test macro __STDC_WANT_IEC_60559_FUNCS_EXT__, from ISO/IEC TS 18661-4:2015, is supported to enable declarations of functions and macros from that TS. * The nonstandard feature selection macros _REENTRANT and _THREAD_SAFE are now treated as compatibility synonyms for _POSIX_C_SOURCE=199506L. * The inclusion of <sys/sysmacros.h> by <sys/types.h> is deprecated. * New <fenv.h> features from TS 18661-1:2014 are added to libm: the fesetexcept, fetestexceptflag, fegetmode and fesetmode functions, the femode_t type and the FE_DFL_MODE and FE_SNANS_ALWAYS_SIGNAL macros. * Integer width macros from TS 18661-1:2014 are added to <limits.h>: CHAR_WIDTH, SCHAR_WIDTH, UCHAR_WIDTH, SHRT_WIDTH, USHRT_WIDTH, INT_WIDTH, UINT_WIDTH, LONG_WIDTH, ULONG_WIDTH, LLONG_WIDTH, ULLONG_WIDTH; and to <stdint.h>: INT8_WIDTH, UINT8_WIDTH, INT16_WIDTH, UINT16_WIDTH, INT32_WIDTH, UINT32_WIDTH, INT64_WIDTH, UINT64_WIDTH, INT_LEAST8_WIDTH, UINT_LEAST8_WIDTH, INT_LEAST16_WIDTH, UINT_LEAST16_WIDTH, INT_LEAST32_WIDTH, UINT_LEAST32_WIDTH, INT_LEAST64_WIDTH, UINT_LEAST64_WIDTH, INT_FAST8_WIDTH, UINT_FAST8_WIDTH, INT_FAST16_WIDTH, UINT_FAST16_WIDTH, INT_FAST32_WIDTH, UINT_FAST32_WIDTH, INT_FAST64_WIDTH, UINT_FAST64_WIDTH, INTPTR_WIDTH, UINTPTR_WIDTH, INTMAX_WIDTH, UINTMAX_WIDTH, PTRDIFF_WIDTH, SIG_ATOMIC_WIDTH, SIZE_WIDTH, WCHAR_WIDTH, WINT_WIDTH. * New <math.h> features are added from TS 18661-1:2014: - Signaling NaN macros: SNANF, SNAN, SNANL. OBS-URL: https://build.opensuse.org/request/show/454919 OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=451
468 lines
13 KiB
Diff
468 lines
13 KiB
Diff
Fix fnmatch handling of collating elements (BZ #17396, BZ #16976)
|
|
|
|
[BZ #16976]
|
|
[BZ #17396]
|
|
* posix/fnmatch_loop.c (internal_fnmatch, internal_fnwmatch): When
|
|
looking up collating elements match against (wide) character
|
|
sequence instead of name. Correct alignment adjustment.
|
|
* posix/fnmatch.c: Don't include "../locale/elem-hash.h".
|
|
* posix/Makefile (tests): Add tst-fnmatch4 and tst-fnmatch5.
|
|
* posix/tst-fnmatch4.c: New file.
|
|
* posix/tst-fnmatch5.c: New file.
|
|
|
|
Index: glibc-2.22/posix/Makefile
|
|
===================================================================
|
|
--- glibc-2.22.orig/posix/Makefile
|
|
+++ glibc-2.22/posix/Makefile
|
|
@@ -87,6 +87,7 @@ tests := tstgetopt testfnm runtests run
|
|
bug-getopt5 tst-getopt_long1 bug-regex34 bug-regex35 \
|
|
tst-pathconf tst-getaddrinfo4 tst-rxspencer-no-utf8 \
|
|
tst-fnmatch3 bug-regex36 tst-getaddrinfo5 \
|
|
+ tst-fnmatch4 tst-fnmatch5 \
|
|
tst-posix_spawn-fd \
|
|
tst-posix_fadvise tst-posix_fadvise64
|
|
xtests := bug-ga2
|
|
Index: glibc-2.22/posix/fnmatch.c
|
|
===================================================================
|
|
--- glibc-2.22.orig/posix/fnmatch.c
|
|
+++ glibc-2.22/posix/fnmatch.c
|
|
@@ -53,7 +53,6 @@
|
|
we support a correct implementation only in glibc. */
|
|
#ifdef _LIBC
|
|
# include "../locale/localeinfo.h"
|
|
-# include "../locale/elem-hash.h"
|
|
# include "../locale/coll-lookup.h"
|
|
# include <shlib-compat.h>
|
|
|
|
Index: glibc-2.22/posix/fnmatch_loop.c
|
|
===================================================================
|
|
--- glibc-2.22.orig/posix/fnmatch_loop.c
|
|
+++ glibc-2.22/posix/fnmatch_loop.c
|
|
@@ -503,26 +503,12 @@ FCT (pattern, string, string_end, no_lea
|
|
{
|
|
int32_t table_size;
|
|
const int32_t *symb_table;
|
|
-# if WIDE_CHAR_VERSION
|
|
- char str[c1];
|
|
- unsigned int strcnt;
|
|
-# else
|
|
-# define str (startp + 1)
|
|
-# endif
|
|
const unsigned char *extra;
|
|
int32_t idx;
|
|
int32_t elem;
|
|
- int32_t second;
|
|
- int32_t hash;
|
|
-
|
|
# if WIDE_CHAR_VERSION
|
|
- /* We have to convert the name to a single-byte
|
|
- string. This is possible since the names
|
|
- consist of ASCII characters and the internal
|
|
- representation is UCS4. */
|
|
- for (strcnt = 0; strcnt < c1; ++strcnt)
|
|
- str[strcnt] = startp[1 + strcnt];
|
|
-#endif
|
|
+ int32_t *wextra;
|
|
+# endif
|
|
|
|
table_size =
|
|
_NL_CURRENT_WORD (LC_COLLATE,
|
|
@@ -534,71 +520,55 @@ FCT (pattern, string, string_end, no_lea
|
|
_NL_CURRENT (LC_COLLATE,
|
|
_NL_COLLATE_SYMB_EXTRAMB);
|
|
|
|
- /* Locate the character in the hashing table. */
|
|
- hash = elem_hash (str, c1);
|
|
-
|
|
- idx = 0;
|
|
- elem = hash % table_size;
|
|
- if (symb_table[2 * elem] != 0)
|
|
- {
|
|
- second = hash % (table_size - 2) + 1;
|
|
-
|
|
- do
|
|
- {
|
|
- /* First compare the hashing value. */
|
|
- if (symb_table[2 * elem] == hash
|
|
- && (c1
|
|
- == extra[symb_table[2 * elem + 1]])
|
|
- && memcmp (str,
|
|
- &extra[symb_table[2 * elem
|
|
- + 1]
|
|
- + 1], c1) == 0)
|
|
- {
|
|
- /* Yep, this is the entry. */
|
|
- idx = symb_table[2 * elem + 1];
|
|
- idx += 1 + extra[idx];
|
|
- break;
|
|
- }
|
|
-
|
|
- /* Next entry. */
|
|
- elem += second;
|
|
- }
|
|
- while (symb_table[2 * elem] != 0);
|
|
- }
|
|
+ for (elem = 0; elem < table_size; elem++)
|
|
+ if (symb_table[2 * elem] != 0)
|
|
+ {
|
|
+ idx = symb_table[2 * elem + 1];
|
|
+ /* Skip the name of collating element. */
|
|
+ idx += 1 + extra[idx];
|
|
+# if WIDE_CHAR_VERSION
|
|
+ /* Skip the byte sequence of the
|
|
+ collating element. */
|
|
+ idx += 1 + extra[idx];
|
|
+ /* Adjust for the alignment. */
|
|
+ idx = (idx + 3) & ~3;
|
|
+
|
|
+ wextra = (int32_t *) &extra[idx + 4];
|
|
+
|
|
+ if (/* Compare the length of the sequence. */
|
|
+ c1 == wextra[0]
|
|
+ /* Compare the wide char sequence. */
|
|
+ && memcmp (startp + 1, &wextra[1],
|
|
+ c1 * sizeof (UCHAR)) == 0)
|
|
+ /* Yep, this is the entry. */
|
|
+ break;
|
|
+# else
|
|
+ if (/* Compare the length of the sequence. */
|
|
+ c1 == extra[idx]
|
|
+ /* Compare the byte sequence. */
|
|
+ && memcmp (startp + 1,
|
|
+ &extra[idx + 1], c1) == 0)
|
|
+ /* Yep, this is the entry. */
|
|
+ break;
|
|
+# endif
|
|
+ }
|
|
|
|
- if (symb_table[2 * elem] != 0)
|
|
+ if (elem < table_size)
|
|
{
|
|
/* Compare the byte sequence but only if
|
|
this is not part of a range. */
|
|
-# if WIDE_CHAR_VERSION
|
|
- int32_t *wextra;
|
|
+ if (! is_range
|
|
|
|
- idx += 1 + extra[idx];
|
|
- /* Adjust for the alignment. */
|
|
- idx = (idx + 3) & ~3;
|
|
-
|
|
- wextra = (int32_t *) &extra[idx + 4];
|
|
-# endif
|
|
-
|
|
- if (! is_range)
|
|
- {
|
|
# if WIDE_CHAR_VERSION
|
|
- for (c1 = 0;
|
|
- (int32_t) c1 < wextra[idx];
|
|
- ++c1)
|
|
- if (n[c1] != wextra[1 + c1])
|
|
- break;
|
|
-
|
|
- if ((int32_t) c1 == wextra[idx])
|
|
- goto matched;
|
|
+ && memcmp (n, &wextra[1],
|
|
+ c1 * sizeof (UCHAR)) == 0
|
|
# else
|
|
- for (c1 = 0; c1 < extra[idx]; ++c1)
|
|
- if (n[c1] != extra[1 + c1])
|
|
- break;
|
|
-
|
|
- if (c1 == extra[idx])
|
|
- goto matched;
|
|
+ && memcmp (n, &extra[idx + 1], c1) == 0
|
|
# endif
|
|
+ )
|
|
+ {
|
|
+ n += c1 - 1;
|
|
+ goto matched;
|
|
}
|
|
|
|
/* Get the collation sequence value. */
|
|
@@ -606,9 +576,9 @@ FCT (pattern, string, string_end, no_lea
|
|
# if WIDE_CHAR_VERSION
|
|
cold = wextra[1 + wextra[idx]];
|
|
# else
|
|
- /* Adjust for the alignment. */
|
|
idx += 1 + extra[idx];
|
|
- idx = (idx + 3) & ~4;
|
|
+ /* Adjust for the alignment. */
|
|
+ idx = (idx + 3) & ~3;
|
|
cold = *((int32_t *) &extra[idx]);
|
|
# endif
|
|
|
|
@@ -618,10 +588,10 @@ FCT (pattern, string, string_end, no_lea
|
|
{
|
|
/* No valid character. Match it as a
|
|
single byte. */
|
|
- if (!is_range && *n == str[0])
|
|
+ if (!is_range && *n == startp[1])
|
|
goto matched;
|
|
|
|
- cold = str[0];
|
|
+ cold = startp[1];
|
|
c = *p++;
|
|
}
|
|
else
|
|
@@ -629,7 +599,6 @@ FCT (pattern, string, string_end, no_lea
|
|
}
|
|
}
|
|
else
|
|
-# undef str
|
|
#endif
|
|
{
|
|
c = FOLD (c);
|
|
@@ -721,25 +690,11 @@ FCT (pattern, string, string_end, no_lea
|
|
{
|
|
int32_t table_size;
|
|
const int32_t *symb_table;
|
|
-# if WIDE_CHAR_VERSION
|
|
- char str[c1];
|
|
- unsigned int strcnt;
|
|
-# else
|
|
-# define str (startp + 1)
|
|
-# endif
|
|
const unsigned char *extra;
|
|
int32_t idx;
|
|
int32_t elem;
|
|
- int32_t second;
|
|
- int32_t hash;
|
|
-
|
|
# if WIDE_CHAR_VERSION
|
|
- /* We have to convert the name to a single-byte
|
|
- string. This is possible since the names
|
|
- consist of ASCII characters and the internal
|
|
- representation is UCS4. */
|
|
- for (strcnt = 0; strcnt < c1; ++strcnt)
|
|
- str[strcnt] = startp[1 + strcnt];
|
|
+ int32_t *wextra;
|
|
# endif
|
|
|
|
table_size =
|
|
@@ -752,51 +707,44 @@ FCT (pattern, string, string_end, no_lea
|
|
_NL_CURRENT (LC_COLLATE,
|
|
_NL_COLLATE_SYMB_EXTRAMB);
|
|
|
|
- /* Locate the character in the hashing
|
|
- table. */
|
|
- hash = elem_hash (str, c1);
|
|
-
|
|
- idx = 0;
|
|
- elem = hash % table_size;
|
|
- if (symb_table[2 * elem] != 0)
|
|
- {
|
|
- second = hash % (table_size - 2) + 1;
|
|
-
|
|
- do
|
|
- {
|
|
- /* First compare the hashing value. */
|
|
- if (symb_table[2 * elem] == hash
|
|
- && (c1
|
|
- == extra[symb_table[2 * elem + 1]])
|
|
- && memcmp (str,
|
|
- &extra[symb_table[2 * elem + 1]
|
|
- + 1], c1) == 0)
|
|
- {
|
|
- /* Yep, this is the entry. */
|
|
- idx = symb_table[2 * elem + 1];
|
|
- idx += 1 + extra[idx];
|
|
- break;
|
|
- }
|
|
-
|
|
- /* Next entry. */
|
|
- elem += second;
|
|
- }
|
|
- while (symb_table[2 * elem] != 0);
|
|
- }
|
|
-
|
|
- if (symb_table[2 * elem] != 0)
|
|
- {
|
|
- /* Compare the byte sequence but only if
|
|
- this is not part of a range. */
|
|
+ for (elem = 0; elem < table_size; elem++)
|
|
+ if (symb_table[2 * elem] != 0)
|
|
+ {
|
|
+ idx = symb_table[2 * elem + 1];
|
|
+ /* Skip the name of collating
|
|
+ element. */
|
|
+ idx += 1 + extra[idx];
|
|
# if WIDE_CHAR_VERSION
|
|
- int32_t *wextra;
|
|
-
|
|
- idx += 1 + extra[idx];
|
|
- /* Adjust for the alignment. */
|
|
- idx = (idx + 3) & ~4;
|
|
-
|
|
- wextra = (int32_t *) &extra[idx + 4];
|
|
+ /* Skip the byte sequence of the
|
|
+ collating element. */
|
|
+ idx += 1 + extra[idx];
|
|
+ /* Adjust for the alignment. */
|
|
+ idx = (idx + 3) & ~3;
|
|
+
|
|
+ wextra = (int32_t *) &extra[idx + 4];
|
|
+
|
|
+ if (/* Compare the length of the
|
|
+ sequence. */
|
|
+ c1 == wextra[0]
|
|
+ /* Compare the wide char sequence. */
|
|
+ && memcmp (startp + 1, &wextra[1],
|
|
+ c1 * sizeof (int32_t)) == 0)
|
|
+ /* Yep, this is the entry. */
|
|
+ break;
|
|
+# else
|
|
+ if (/* Compare the length of the
|
|
+ sequence. */
|
|
+ c1 == extra[idx]
|
|
+ /* Compare the byte sequence. */
|
|
+ && memcmp (startp + 1,
|
|
+ &extra[idx + 1], c1) == 0)
|
|
+ /* Yep, this is the entry. */
|
|
+ break;
|
|
# endif
|
|
+ }
|
|
+
|
|
+ if (elem < table_size)
|
|
+ {
|
|
/* Get the collation sequence value. */
|
|
is_seqval = 1;
|
|
# if WIDE_CHAR_VERSION
|
|
@@ -804,19 +752,18 @@ FCT (pattern, string, string_end, no_lea
|
|
# else
|
|
/* Adjust for the alignment. */
|
|
idx += 1 + extra[idx];
|
|
- idx = (idx + 3) & ~4;
|
|
+ idx = (idx + 3) & ~3;
|
|
cend = *((int32_t *) &extra[idx]);
|
|
# endif
|
|
}
|
|
- else if (symb_table[2 * elem] != 0 && c1 == 1)
|
|
+ else if (c1 == 1)
|
|
{
|
|
- cend = str[0];
|
|
+ cend = startp[1];
|
|
c = *p++;
|
|
}
|
|
else
|
|
return FNM_NOMATCH;
|
|
}
|
|
-# undef str
|
|
}
|
|
else
|
|
{
|
|
Index: glibc-2.22/posix/tst-fnmatch4.c
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ glibc-2.22/posix/tst-fnmatch4.c
|
|
@@ -0,0 +1,51 @@
|
|
+/* Test for fnmatch handling of collating elements
|
|
+ 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 <stdio.h>
|
|
+#include <locale.h>
|
|
+#include <fnmatch.h>
|
|
+
|
|
+static int
|
|
+do_test_locale (const char *locale)
|
|
+{
|
|
+ const char *pattern = "[[.ll.]]";
|
|
+
|
|
+ if (setlocale (LC_ALL, locale) == NULL)
|
|
+ {
|
|
+ printf ("could not set locale %s\n", locale);
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
+ if (fnmatch (pattern, "ll", 0) != 0)
|
|
+ {
|
|
+ printf ("%s didn't match in locale %s\n", pattern, locale);
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int
|
|
+do_test (void)
|
|
+{
|
|
+ return (do_test_locale ("es_US.ISO-8859-1")
|
|
+ || do_test_locale ("es_US.UTF-8"));
|
|
+}
|
|
+
|
|
+#define TEST_FUNCTION do_test ()
|
|
+#include "../test-skeleton.c"
|
|
Index: glibc-2.22/posix/tst-fnmatch5.c
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ glibc-2.22/posix/tst-fnmatch5.c
|
|
@@ -0,0 +1,53 @@
|
|
+/* Test for fnmatch handling of collating elements
|
|
+ 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 <fnmatch.h>
|
|
+#include <locale.h>
|
|
+#include <stdio.h>
|
|
+#include <string.h>
|
|
+
|
|
+#define LENGTH 20000000
|
|
+
|
|
+char pattern[LENGTH + 7];
|
|
+
|
|
+static int
|
|
+do_test (void)
|
|
+{
|
|
+ if (setlocale (LC_ALL, "en_US.UTF-8") == NULL)
|
|
+ {
|
|
+ puts ("could not set locale");
|
|
+ return 1;
|
|
+ }
|
|
+ pattern[0] = '[';
|
|
+ pattern[1] = '[';
|
|
+ pattern[2] = '.';
|
|
+ memset (pattern + 3, 'a', LENGTH);
|
|
+ pattern[LENGTH + 3] = '.';
|
|
+ pattern[LENGTH + 4] = ']';
|
|
+ pattern[LENGTH + 5] = ']';
|
|
+ int ret = fnmatch (pattern, "a", 0);
|
|
+ if (ret == 0)
|
|
+ {
|
|
+ puts ("fnmatch returned 0 for invalid pattern");
|
|
+ return 1;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+#define TEST_FUNCTION do_test ()
|
|
+#include "../test-skeleton.c"
|