On Fri, Jan 09, 2009 at 09:33:45AM +0100, Paolo Bonzini wrote:
> This was bug 9697 in glibc's bugzilla, and is fixed by the patch at "git
> diff 4c2a6f3d 37bdc055ce^" in git://sources.redhat.com/git/glibc.git
> (gitweb interface at http://repo.or.cz/w/glibc.git).
> 
> Another regex bug (bug 697 in glibc's bugzilla), by the way, is fixed by
> the patch at "git diff 37bdc055^ 9d565658".

Attaching those two for posterity.
diff --git a/ChangeLog b/ChangeLog
index 182bd26..8829b44 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2009-01-04  Paolo Bonzini  <bonz...@gnu.org>
+
+       [BZ 9697]
+       * posix/bug-regex17.c: Add testcases.
+       * posix/regcomp.c (re_compile_fastmap_iter): Rewrite COMPLEX_BRACKET
+       handling.
+
 2009-01-05  Martin Schwidefsky  <schwidef...@de.ibm.com>
 
        * sysdeps/unix/sysv/linux/s390/bits/libc-vdso.h: New file.
diff --git a/posix/bug-regex17.c b/posix/bug-regex17.c
index b42f9b6..1c11a1d 100644
--- a/posix/bug-regex17.c
+++ b/posix/bug-regex17.c
@@ -1,5 +1,5 @@
-/* Turkish regular expression tests.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* German regular expression tests.
+   Copyright (C) 2002, 2003, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <ja...@redhat.com>, 2002.
 
@@ -33,10 +33,10 @@ struct
   int flags, nmatch;
   regmatch_t rm[5];
 } tests[] = {
-  /* \xc3\x84  LATIN CAPITAL LETTER A WITH DIAERESIS
-     \xc3\x96  LATIN CAPITAL LETTER O WITH DIAERESIS
-     \xc3\xa4  LATIN SMALL LETTER A WITH DIAERESIS
-     \xc3\xb6  LATIN SMALL LETTER O WITH DIAERESIS  */
+  /* U+00C4    \xc3\x84        LATIN CAPITAL LETTER A WITH DIAERESIS
+     U+00D6    \xc3\x96        LATIN CAPITAL LETTER O WITH DIAERESIS
+     U+00E4    \xc3\xa4        LATIN SMALL LETTER A WITH DIAERESIS
+     U+00F6    \xc3\xb6        LATIN SMALL LETTER O WITH DIAERESIS  */
   { "\xc3\x84\xc3\x96*\xc3\xb6$", "aB\xc3\xa4\xc3\xb6\xc3\xb6\xc3\x96", 
REG_ICASE, 2,
     { { 2, 10 }, { -1, -1 } } },
   { "[\xc3\x84x]\xc3\x96*\xc3\xb6$", "aB\xc3\x84\xc3\xb6\xc3\xb6\xc3\x96", 
REG_ICASE, 2,
@@ -45,10 +45,22 @@ struct
     { { 2, 10 }, { -1, -1 } } },
   { "[^x]\xc3\x96*\xc3\xb6$", "aB\xc3\xa4\xc3\xb6\xc3\xb6\xc3\x96", REG_ICASE, 
2,
     { { 2, 10 }, { -1, -1 } } },
+
+  /* Tests for bug 9697:
+     U+00DF    \xc3\x9f        LATIN SMALL LETTER SHARP S
+     U+02DA    \xcb\x9a        RING ABOVE
+     U+02E2    \xcb\xa2        MODIFIER LETTER SMALL S  */
+  { "[a-z]|[^a-z]", "\xcb\xa2", REG_EXTENDED, 2,
+    { { 0, 2 }, { -1, -1 } } },
+  { "[a-z]", "\xc3\x9f", REG_EXTENDED, 2,
+    { { 0, 2 }, { -1, -1 } } },
+  { "[^a-z]", "\xcb\x9a", REG_EXTENDED, 2,
+    { { 0, 2 }, { -1, -1 } } },
 };
 
-int
-main (void)
+
+static int
+do_test (void)
 {
   regex_t re;
   regmatch_t rm[5];
@@ -93,3 +105,6 @@ main (void)
 
   return ret;
 }
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/posix/regcomp.c b/posix/regcomp.c
index d5a0535..4843cfe 100644
--- a/posix/regcomp.c
+++ b/posix/regcomp.c
@@ -1,5 +1,6 @@
 /* Extended regular expression matching and search library.
-   Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
+   Copyright (C) 2002,2003,2004,2005,2006,2007,2009
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Isamu Hasegawa <is...@yamato.ibm.com>.
 
@@ -350,47 +351,67 @@ re_compile_fastmap_iter (regex_t *bufp, const 
re_dfastate_t *init_state,
 #ifdef RE_ENABLE_I18N
       else if (type == COMPLEX_BRACKET)
        {
-         int i;
          re_charset_t *cset = dfa->nodes[node].opr.mbcset;
-         if (cset->non_match || cset->ncoll_syms || cset->nequiv_classes
-             || cset->nranges || cset->nchar_classes)
-           {
+         int i;
+
 # ifdef _LIBC
-             if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0)
+         /* See if we have to try all bytes which start multiple collation
+            elements.
+            e.g. In da_DK, we want to catch 'a' since "aa" is a valid
+                 collation element, and don't catch 'b' since 'b' is
+                 the only collation element which starts from 'b' (and
+                 it is caught by SIMPLE_BRACKET).  */
+             if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0
+                 && (cset->ncoll_syms || cset->nranges))
                {
-                 /* In this case we want to catch the bytes which are
-                    the first byte of any collation elements.
-                    e.g. In da_DK, we want to catch 'a' since "aa"
-                         is a valid collation element, and don't catch
-                         'b' since 'b' is the only collation element
-                         which starts from 'b'.  */
                  const int32_t *table = (const int32_t *)
                    _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
                  for (i = 0; i < SBC_MAX; ++i)
                    if (table[i] < 0)
                      re_set_fastmap (fastmap, icase, i);
                }
-# else
-             if (dfa->mb_cur_max > 1)
-               for (i = 0; i < SBC_MAX; ++i)
-                 if (__btowc (i) == WEOF)
-                   re_set_fastmap (fastmap, icase, i);
-# endif /* not _LIBC */
-           }
-         for (i = 0; i < cset->nmbchars; ++i)
+# endif /* _LIBC */
+
+         /* See if we have to start the match at all multibyte characters,
+            i.e. where we would not find an invalid sequence.  This only
+            applies to multibyte character sets; for single byte character
+            sets, the SIMPLE_BRACKET again suffices.  */
+         if (dfa->mb_cur_max > 1
+             && (cset->nchar_classes || cset->non_match
+# ifdef _LIBC
+                 || cset->nequiv_classes
+# endif /* _LIBC */
+                ))
            {
-             char buf[256];
-             mbstate_t state;
-             memset (&state, '\0', sizeof (state));
-             if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1)
-               re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
-             if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
+             unsigned char c = 0;
+             do
                {
-                 if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state)
-                     != (size_t) -1)
-                   re_set_fastmap (fastmap, 0, *(unsigned char *) buf);
+                 mbstate_t mbs;
+                 memset (&mbs, 0, sizeof (mbs));
+                 if (__mbrtowc (NULL, (char *) &c, 1, &mbs) == (size_t) -2)
+                   re_set_fastmap (fastmap, false, (int) c);
                }
+             while (++c != 0);
            }
+
+         else
+           {
+             /* ... Else catch all bytes which can start the mbchars.  */
+             for (i = 0; i < cset->nmbchars; ++i)
+               {
+                 char buf[256];
+                 mbstate_t state;
+                 memset (&state, '\0', sizeof (state));
+                 if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1)
+                   re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
+                 if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
+                   {
+                     if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state)
+                         != (size_t) -1)
+                       re_set_fastmap (fastmap, false, *(unsigned char *) buf);
+                   }
+               }
+           }
        }
 #endif /* RE_ENABLE_I18N */
       else if (type == OP_PERIOD
diff --git a/ChangeLog b/ChangeLog
index 8829b44..17e987b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2009-01-05  Paolo Bonzini  <bonz...@gnu.org>
+
+       [BZ 697]
+       * posix/regexec.c (prune_impossible_nodes): Handle sifted_states[0]
+       being NULL also if there are no backreferences.
+       * posix/rxspencer/tests: Add testcases.
+
 2009-01-04  Paolo Bonzini  <bonz...@gnu.org>
 
        [BZ 9697]
diff --git a/posix/regexec.c b/posix/regexec.c
index 135efe7..7bf0c08 100644
--- a/posix/regexec.c
+++ b/posix/regexec.c
@@ -1,5 +1,5 @@
 /* Extended regular expression matching and search library.
-   Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2009 Free Software Foundation, 
Inc.
    This file is part of the GNU C Library.
    Contributed by Isamu Hasegawa <is...@yamato.ibm.com>.
 
@@ -1004,6 +1004,11 @@ prune_impossible_nodes (mctx)
       re_node_set_free (&sctx.limits);
       if (BE (ret != REG_NOERROR, 0))
        goto free_return;
+      if (sifted_states[0] == NULL)
+       {
+         ret = REG_NOMATCH;
+         goto free_return;
+       }
     }
   re_free (mctx->state_log);
   mctx->state_log = sifted_states;
diff --git a/posix/rxspencer/tests b/posix/rxspencer/tests
index b84a270..3ad46e2 100644
--- a/posix/rxspencer/tests
+++ b/posix/rxspencer/tests
@@ -536,3 +536,7 @@ a.*\b       &       abT     ab
 \B     &       aSbTc
 \B     &       SaT     @SaT
 \B     &       aSTSb   @TSb
+
+o$($|.)        -       oN
+o$($|.)        -       op
+o$($|.)        -       o       o

Reply via email to