Regex fails when string is too long
hv@crypt.org [Mon, 6 Jul 2009 14:45:12 +0000 (15:45 +0100)]
This looks to be a simple oversight. All tests pass here.

Hugo

Signed-off-by: H.Merijn Brand <h.m.brand@xs4all.nl>

regexec.c
t/op/pat.t

index 93fadab..f3c9540 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -4411,7 +4411,7 @@ NULL
        case CURLYM:    /* /A{m,n}B/ where A is fixed-length */
 
            /* This is an optimisation of CURLYX that enables us to push
-            * only a single backtracking state, no matter now many matches
+            * only a single backtracking state, no matter how many matches
             * there are in {m,n}. It relies on the pattern being constant
             * length, with no parens to influence future backrefs
             */
@@ -4574,7 +4574,8 @@ NULL
        case CURLYM_B_fail: /* just failed to match a B */
            REGCP_UNWIND(ST.cp);
            if (ST.minmod) {
-               if (ST.count == ARG2(ST.me) /* max */)
+               I32 max = ARG2(ST.me);
+               if (max != REG_INFTY && ST.count == max)
                    sayNO;
                goto curlym_do_A; /* try to match a further A */
            }
index 62ca4b2..aa6299f 100644 (file)
@@ -13,7 +13,7 @@ sub run_tests;
 
 $| = 1;
 
-my $EXPECTED_TESTS = 4061;  # Update this when adding/deleting tests.
+my $EXPECTED_TESTS = 4065;  # Update this when adding/deleting tests.
 
 BEGIN {
     chdir 't' if -d 't';
@@ -4346,6 +4346,21 @@ sub run_tests {
             iseq($str, "\$1 = undef, \$2 = undef, \$3 = undef, \$4 = undef, \$5 = undef, \$^R = undef");
        }
     }
+
+    {
+       local $BugId = 65372;   # minimal CURLYM limited to 32767 matches
+       my @pat = (
+           qr{a(x|y)*b},       # CURLYM
+           qr{a(x|y)*?b},      # .. with minmod
+           qr{a([wx]|[yz])*b}, # .. and without tries
+           qr{a([wx]|[yz])*?b},
+       );
+       my $len = 32768;
+       my $s = join '', 'a', 'x' x $len, 'b';
+       for my $pat (@pat) {
+           ok($s =~ $pat, $pat);
+       }
+    }
     #
     # This should be the last test.
     #