This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Assertion fails in multi-char regex match
authorKarl Williamson <public@khwilliamson.com>
Fri, 13 May 2011 14:35:23 +0000 (08:35 -0600)
committerKarl Williamson <public@khwilliamson.com>
Wed, 18 May 2011 16:52:39 +0000 (10:52 -0600)
In '"s\N{U+DF}" =~ /\x{00DF}/i, the LHS folds to 'sss', the RHS to 'ss'.
The bug occurs when the RHS tries to match the first two es's, but that
splits the LHS \xDF character, which Perl doesn't know how to handle,
and the assertion got triggered.  (This is similar to [perl #72998].)

The solution adopted here is to disallow a partial character match,
as #72998 did as well.

regexec.c
t/re/pat_advanced.t

index 391fc16..fd90ad7 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -6726,9 +6726,12 @@ S_reginclass(pTHX_ const regexp * const prog, register const regnode * const n,
                            STRLEN len;
                            const char * const s = SvPV_const(sv, len);
 
-                           if (len <= total_foldlen && memEQ(s,
-                                                              (char*)folded,
-                                                              len))
+                           if (len <= total_foldlen
+                               && memEQ(s, (char*)folded, len)
+
+                                  /* If 0, means matched a partial char. See
+                                   * [perl #90536] */
+                               && map_fold_len_back[len])
                            {
 
                                /* Advance the target string ptr to account for
@@ -6737,7 +6740,6 @@ S_reginclass(pTHX_ const regexp * const prog, register const regnode * const n,
                                 * length. */
                                if (lenp) {
                                    *lenp = map_fold_len_back[len];
-                                   assert(*lenp != 0); /* Otherwise will loop */
                                }
                                match = TRUE;
                                break;
index 6d7624d..2a510d1 100644 (file)
@@ -2108,6 +2108,10 @@ EOP
         like("\x{00DF}", qr/[\x{1E9E}_]*/i, "\"\\x{00DF}\" =~ /[\\x{1E9E}_]*/i was looping");
     }
 
+    {   # Bug #90536, caused failed assertion
+        unlike("s\N{U+DF}", qr/^\x{00DF}/i, "\"s\\N{U+DF}\", qr/^\\x{00DF}/i");
+    }
+
     # !!! NOTE that tests that aren't at all likely to crash perl should go
     # a ways above, above these last ones.