diff options
author | Yves Orton <demerphq@gmail.com> | 2023-01-13 18:23:01 +0100 |
---|---|---|
committer | Yves Orton <demerphq@gmail.com> | 2023-01-13 20:24:28 +0100 |
commit | 61e2c0af14d6f848fd8f2ca85beeeb8363365321 (patch) | |
tree | fd216903af873a9ca48385ce53cb413d58ec10a4 | |
parent | 1b3de34b7cfc0bdda5cfe9dbb2690bf5b8faeed1 (diff) | |
download | perl-61e2c0af14d6f848fd8f2ca85beeeb8363365321.tar.gz |
regexec.c - avoid calling regrepeat when the max is 0
When we have a max quantifier of 0, then the quantified
item is essentially a NOTHING reop. Regardless, we do not
need to call regrepeat, and doing so confuses some of the
logic it contains. Simply avoiding calling regrepeat()
fixes the underlying issue, and avoids the broken code.
This fixes GH Issue #20690.
-rw-r--r-- | regexec.c | 7 | ||||
-rw-r--r-- | t/re/subst.t | 19 |
2 files changed, 24 insertions, 2 deletions
@@ -9316,7 +9316,10 @@ NULL /* avoid taking address of locinput, so it can remain * a register var */ char *li = locinput; - ST.count = regrepeat(rex, &li, ST.A, loceol, reginfo, ST.max); + if (ST.max) + ST.count = regrepeat(rex, &li, ST.A, loceol, reginfo, ST.max); + else + ST.count = 0; if (ST.count < ST.min) sayNO; SET_locinput(li); @@ -10058,6 +10061,8 @@ S_regrepeat(pTHX_ regexp *prog, char **startposp, const regnode *p, unsigned int to_complement = 0; /* Invert the result? */ char_class_number_ classnum; + assert(max); + PERL_ARGS_ASSERT_REGREPEAT; /* This routine is structured so that we switch on the input OP. Each OP diff --git a/t/re/subst.t b/t/re/subst.t index b9e61ce758..4ab0c220a9 100644 --- a/t/re/subst.t +++ b/t/re/subst.t @@ -11,7 +11,7 @@ BEGIN { require './loc_tools.pl'; } -plan(tests => 278); +plan(tests => 281); $_ = 'david'; $a = s/david/rules/r; @@ -1183,3 +1183,20 @@ __EOF__ { fresh_perl_is("s//00000000000format \0 '0000000\\x{800}/;eval", "", {}, "RT #133882"); } + +{ # GH Issue 20690 + my @ret; + my $str = "abc"; + for my $upgrade (0,1) { + my $copy = $str; + utf8::upgrade($copy) if $upgrade; + my $r= $copy=~s/b{0}//gr; + push @ret, $r; + } + is( $ret[1], $ret[0], + "Issue #20690 - s/b{0}//gr should work the same for utf8 and non-utf8 strings"); + is( $ret[0], $str, + "Issue #20690 - s/b{0}//gr on non-utf8 string should not remove anything"); + is( $ret[1], $str, + "Issue #20690 - s/b{0}//gr on utf8 string should not remove anything"); +} |