From: David Mitchell Date: Fri, 7 Feb 2014 16:43:19 +0000 (+0000) Subject: re_intuit_start(): don't decrease other_last X-Git-Tag: upstream/5.20.0~464^2~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ec19cf6bc850473f27f9bb92a316cd58fd76797c;p=platform%2Fupstream%2Fperl.git re_intuit_start(): don't decrease other_last The /^../m failure code did an unconditional other_last = rx_origin; if other_last was already high, it could get shrunk and we'd end up running fbm over the same bit of string repeatedly. The following code $s = "-ab\n" x 500_000; $s .= 'abx'; $s =~ /^ab.*x/m; (which went quadratic on length) reduces from minutes to millisecs with this commit. This is because we'd keep going back to near the beginning of the string and searching for 'x' again. --- diff --git a/regexec.c b/regexec.c index 181afe7..ed6f9fc 100644 --- a/regexec.c +++ b/regexec.c @@ -1121,7 +1121,8 @@ Perl_re_intuit_start(pTHX_ DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, " Found /%s^%s/m, restarting lookup for check-string at offset %ld...\n", PL_colors[0], PL_colors[1], (long)(t + 1 - strpos))); - other_last = rx_origin; + if (other_last < rx_origin) + other_last = rx_origin; goto restart; } diff --git a/t/re/pat.t b/t/re/pat.t index 486238c..79c7e6a 100644 --- a/t/re/pat.t +++ b/t/re/pat.t @@ -20,7 +20,7 @@ BEGIN { require './test.pl'; } -plan tests => 716; # Update this when adding/deleting tests. +plan tests => 717; # Update this when adding/deleting tests. run_tests() unless caller; @@ -1534,6 +1534,10 @@ EOP utf8::upgrade($s); ok($s =~ /\da\d{0,30000}bc/, "\\d{30000}"); + $s = "-ab\n" x 250_000; + $s .= "abx"; + ok($s =~ /^ab.*x/m, "distant float with /m"); + } # These are based on looking at the code in regcomp.c