PATCH: [perl #120041] regcomp.c missing parens and broken STCLASS
authorKarl Williamson <public@khwilliamson.com>
Mon, 30 Sep 2013 20:06:23 +0000 (14:06 -0600)
committerKarl Williamson <public@khwilliamson.com>
Mon, 30 Sep 2013 20:26:41 +0000 (14:26 -0600)
This was caused by a problem in commit
43a64b8b430604bd4d76fd256a5babdccaf0ab2b
which was masked by problems in commit
a0dd42312a1f26356d2fdf49656e45b77c2cefb5.

The first commit deleted a line it shouldn't have.  I thought that a
variable wasn't modified before reaching that line, but it turns out it
was because another variable is set to point to its address, and was
modified inside a subroutine call.  The other two lines deleted in the
first commit are ok to have deleted.

The second commit masked the problems of the first by omitting some
necessary grouping parentheses, which caused things to not work as
intended, and we didn't have a good test case in our suite to find this
problem.  (Thanks to Lukas Mai for spotting the problem and submitting a
test case.)

regcomp.c
t/re/re_tests

index 18897e5..e876378 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -835,7 +835,7 @@ S_ssc_is_anything(pTHX_ const regnode_ssc *ssc)
 
     assert(OP(ssc) == ANYOF_SYNTHETIC);
 
-    if (! ANYOF_FLAGS(ssc) & ANYOF_EMPTY_STRING) {
+    if (! (ANYOF_FLAGS(ssc) & ANYOF_EMPTY_STRING)) {
         return FALSE;
     }
 
@@ -4167,6 +4167,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
                        flags &= ~SCF_DO_STCLASS_AND;
                        StructCopy(&this_class, data->start_class, regnode_ssc);
                        flags |= SCF_DO_STCLASS_OR;
+                        ANYOF_FLAGS(data->start_class) |= ANYOF_EMPTY_STRING;
                    }
                } else {                /* Non-zero len */
                    if (flags & SCF_DO_STCLASS_OR) {
@@ -6613,7 +6614,7 @@ reStudy:
 
        if ((!(r->anchored_substr || r->anchored_utf8) || r->anchored_offset)
            && stclass_flag
-           && ! ANYOF_FLAGS(data.start_class) & ANYOF_EMPTY_STRING
+            && ! (ANYOF_FLAGS(data.start_class) & ANYOF_EMPTY_STRING)
            && !ssc_is_anything(data.start_class))
        {
            const U32 n = add_data(pRExC_state, STR_WITH_LEN("f"));
@@ -6687,9 +6688,9 @@ reStudy:
        r->check_substr = r->check_utf8 = r->anchored_substr = r->anchored_utf8
                = r->float_substr = r->float_utf8 = NULL;
 
-       if (! ANYOF_FLAGS(data.start_class) & ANYOF_EMPTY_STRING
-           && !ssc_is_anything(data.start_class))
-       {
+        if (! (ANYOF_FLAGS(data.start_class) & ANYOF_EMPTY_STRING)
+            && ! ssc_is_anything(data.start_class))
+        {
            const U32 n = add_data(pRExC_state, STR_WITH_LEN("f"));
 
             ssc_finalize(pRExC_state, data.start_class);
index 3c031ff..cf3291d 100644 (file)
@@ -1794,6 +1794,8 @@ A+(*PRUNE)BC(?{}) AAABC   y       $&      AAABC
 (?:(a(*SKIP)b)){0}(?:(?1)|ac)  x       n       -       -
 # RT #119073: PCRE regression test: {0} => NOTHING optimization
 (?1)(?:(b)){0} b       y       $&      b
+# RT #120041
+^A*\z          y       $&      
 
 # Keep these lines at the end of the file
 # vim: softtabstop=0 noexpandtab