From 1aeab75ab913b2442f1de7300d375422255ad122 Mon Sep 17 00:00:00 2001 From: Gurusamy Sarathy Date: Sat, 19 Feb 2000 17:33:59 +0000 Subject: [PATCH] fix bug in backtracking optimizer (from Makoto Ishisone ) p4raw-id: //depot/perl@5151 --- regexec.c | 8 +++++++- t/op/pat.t | 15 ++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/regexec.c b/regexec.c index e63fa6f..f9f2cc0 100644 --- a/regexec.c +++ b/regexec.c @@ -3045,8 +3045,14 @@ S_regmatch(pTHX_ regnode *prog) n = regrepeat(scan, n); locinput = PL_reginput; if (ln < n && PL_regkind[(U8)OP(next)] == EOL && - (!PL_multiline || OP(next) == SEOL)) + (!PL_multiline || OP(next) == SEOL || OP(next) == EOS)) { ln = n; /* why back off? */ + /* ...because $ and \Z can match before *and* after + newline at the end. Consider "\n\n" =~ /\n+\Z\n/. + We should back off by one in this case. */ + if (UCHARAT(PL_reginput - 1) == '\n' && OP(next) != EOS) + ln--; + } REGCP_SET; if (paren) { while (n >= ln) { diff --git a/t/op/pat.t b/t/op/pat.t index 439796d..142b82e 100755 --- a/t/op/pat.t +++ b/t/op/pat.t @@ -4,7 +4,7 @@ # the format supported by op/regexp.t. If you want to add a test # that does fit that format, add it to op/re_tests, not here. -print "1..207\n"; +print "1..210\n"; BEGIN { chdir 't' if -d 't'; @@ -978,3 +978,16 @@ $test++; print "not " if "@b" ne "@c"; print "ok $test\n"; $test++; + +# see if backtracking optimization works correctly +"\n\n" =~ /\n $ \n/x or print "not "; +print "ok $test\n"; +$test++; + +"\n\n" =~ /\n* $ \n/x or print "not "; +print "ok $test\n"; +$test++; + +"\n\n" =~ /\n+ $ \n/x or print "not "; +print "ok $test\n"; +$test++; -- 2.7.4