Commit b27da4016d for perl
commit b27da4016d599e83fbfc511ff49b1004c46e1f0a
Author: Richard Leach <rich+perl@hyphen-dash-hyphen.info>
Date: Fri Oct 9 09:44:18 2026 +0000
regexec.c: CURLY* nodes must clear minmod before shortcut exits
GH #24926 showed that `"aaaa" =~ /(?:x??\x{100})*a+/` matches `a` when it
should match `aaaa`. This was because the non-greedy quantifier attached
to `x??` incorrectly bled over to affect `a+`.
Specifically, the `minmod` flag - which indicates that a non-greedy match
should be performed - was not cleared by some CURLY* regnodes prior to an
early `sayNO` (and similar) jump following an unsuccessful match.
(This bug was inadvertently introduced in 5.18.0.)
This commit adds `minmod = 0` to what look like the affected cases.
diff --git a/pod/perldelta.pod b/pod/perldelta.pod
index 6206d81138..e51767a1d2 100644
--- a/pod/perldelta.pod
+++ b/pod/perldelta.pod
@@ -448,6 +448,14 @@ viable match candidates at the start of the target string being missed.
=item *
+Following an unsuccessful earlier non-greedy match, a regular expression
+intended to perform a separate I<greedy> match could have instead
+performed a I<non-greedy> match because of skipped flag clearance.
+
+[GH #24926]
+
+=item *
+
In some cases warnings that occurred while using unpack on an invalid
UTF-8 marked string would result in an invalid free. [GH #24913]
diff --git a/regexec.c b/regexec.c
index a8860d6ea8..92ca01eeb2 100644
--- a/regexec.c
+++ b/regexec.c
@@ -9696,9 +9696,11 @@ NULL
/* handle the single-char capture called as a GOSUB etc */
if (EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)ST.paren))
{
+ minmod = 0;
char *li = locinput;
- if (!regrepeat(rex, &li, scan, loceol, reginfo, 1))
+ if (!regrepeat(rex, &li, scan, loceol, reginfo, 1)) {
sayNO;
+ }
SET_locinput(li);
goto fake_end;
}
@@ -9740,6 +9742,7 @@ NULL
if (! S_setup_EXACTISH_ST(aTHX_ text_node,
&ST.Binfo, reginfo))
{
+ minmod = 0;
sayNO;
}
}
diff --git a/t/re/re_tests b/t/re/re_tests
index 3abcc0ef42..1f3cc29d82 100644
--- a/t/re/re_tests
+++ b/t/re/re_tests
@@ -2282,6 +2282,12 @@ x+(?:b{2}){2} xxbbbb y $& xxbbbb - quantified sub-pattern after PLUS
\x{e0}+j \x{e0}\x{e9}\x{e0}j y $& \x{e0}j
\x{e0}+j \x{e0}\x{e9}\x{e0}\x{e0}j y $& \x{e0}\x{e0}j
+# GH #24926
+(?:x??\x{100})*a+ aaaa y $& aaaa - minmod cleared by CURLY
+(?:(x)??\x{100})*a+ aaaa y $& aaaa - minmod cleared by CURLYN
+(?:x+?\x{100})*a+ aaaa y $& aaaa - minmod cleared by PLUS
+(?:x*?\x{100})*a+ aaaa y $& aaaa - minmod cleared by STAR
+
# Keep these lines at the end of the file
# pat string y/n/etc expr expected-expr skip-reason comment
# vim: softtabstop=0 noexpandtab