summaryrefslogtreecommitdiff
path: root/regexec.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2014-03-18 20:15:27 +0000
committerDavid Mitchell <davem@iabyn.com>2014-03-19 18:25:54 +0000
commitd0d4464849e2b30aee89c175ccb5465795de10ce (patch)
treee382769db44e1f747ca4726f49287ea46a48267f /regexec.c
parentfe4f3442a740e4a233ab9610229aca3f4cf6a21f (diff)
downloadperl-d0d4464849e2b30aee89c175ccb5465795de10ce.tar.gz
re_intuit_start(): reduce scope of /^...$/m test
Intuit has a quick reject test for a fixed pattern that is anchored at both ends. For example, with the pattern /^abcd$/, only the exact strings "abcd" or "abcd\n" will match; anything else, and the match immediately fails. A fix for [perl #115242] correctly made intuit skip the test in the presence of //m, since in this case the $ doesn't necessarily correspond to the end of the string. However, the fix was too wide in scope; it caused //m patterns to skip searching for a known string anchored just at the start, as well as one anchored at both ends. With this commit, the following code now runs in a few milliseconds rather than a few seconds on my machine: $s = "abcdefg" x 1_000_000; $s =~ /(?-m:^)abcX?fg/m for 1..100;
Diffstat (limited to 'regexec.c')
-rw-r--r--regexec.c7
1 files changed, 2 insertions, 5 deletions
diff --git a/regexec.c b/regexec.c
index 54400f17ac..e3ce022528 100644
--- a/regexec.c
+++ b/regexec.c
@@ -783,10 +783,7 @@ Perl_re_intuit_start(pTHX_
* at position pos()-4+1, which lines up with the "a" */
if (prog->check_offset_min == prog->check_offset_max
- && !(prog->intflags & PREGf_CANY_SEEN)
- && ! multiline) /* /m can cause \n's to match that aren't
- accounted for in the string max length.
- See [perl #115242] */
+ && !(prog->intflags & PREGf_CANY_SEEN))
{
/* Substring at constant offset from beg-of-str... */
SSize_t slen = SvCUR(check);
@@ -798,7 +795,7 @@ Perl_re_intuit_start(pTHX_
" Looking for check substr at fixed offset %"IVdf"...\n",
(IV)prog->check_offset_min));
- if (SvTAIL(check)) {
+ if (SvTAIL(check) && !multiline) {
/* In this case, the regex is anchored at the end too,
* so the lengths must match exactly, give or take a \n.
* NB: slen >= 1 since the last char of check is \n */