Commit 9ebe75cc06 for perl
commit 9ebe75cc062ee92c07ad8b5180711d92eea4b0ac
Author: Yves Orton <demerphq@gmail.com>
Date: Fri Oct 16 12:13:03 2026 +0200
regex: precompute the end of folded start-class scans
We check both the last possible start and the end of the string for
every candidate. Calculate one exclusive limit before the loop instead.
Cap it at strend. HOP3c can leave the last possible start at the end of
a short target, but a nonempty literal cannot match there. Trying it
would leave UTF8_SAFE_SKIP() returning zero without advancing the scan.
diff --git a/regexec.c b/regexec.c
index 9f3d285326..3461560e16 100644
--- a/regexec.c
+++ b/regexec.c
@@ -2887,17 +2887,21 @@ S_find_byclass(pTHX_ regexp * prog, const regnode *c, char *s,
* that would require us to go beyond the end of the string */
e = HOP3c(strend, -((SSize_t)lnc), s);
- /* XXX Note that we could recalculate e to stop the loop earlier,
- * as the worst case expansion above will rarely be met, and as we
- * go along we would usually find that e moves further to the left.
+ /* Convert inclusive e to an exclusive limit capped at strend.
+ * HOP3c can clamp e to s == strend, where a nonempty folded
+ * literal cannot match and UTF8_SAFE_SKIP returns zero,
+ * preventing loop progress. */
+ const char * const scan_end = e < strend ? e + 1 : strend;
+
+ /* XXX Note that we could recalculate scan_end to stop the loop
+ * earlier, as the worst case expansion above will rarely be met,
+ * and as we go along we would usually find that scan_end moves
+ * further to the left.
* This would happen only after we reached the point in the loop
* where if there were no expansion we should fail. Unclear if
* worth the expense */
- /* HOP3c clamps e to s when too few characters remain. A
- * nonempty folded literal cannot match at strend, where
- * UTF8_SAFE_SKIP returns zero and cannot advance the loop. */
- while (s < strend && s <= e) {
+ while (s < scan_end) {
char *my_strend= (char *)strend;
if ( foldEQ_utf8_flags(s, &my_strend, 0, utf8_target,
pat_string, NULL, ln, is_utf8_pat,