Commit 8575930148 for perl

commit 8575930148ecf74a3606c0152fe7a5d922ce300d
Author: Richard Leach <rich+perl@hyphen-dash-hyphen.info>
Date:   Thu Oct 15 22:58:23 2026 +0000

    Perl_make_trie: allow minlen and maxlen to both change

    Prior to this commit, as the separate alternations of a soon-to-be TRIE
    were being processed, an alternation could modify the _minlen_ of the
    TRIE **or** the _maxlen_. However, some folding characters could
    necessitate modifying the _minlen_ **and** the _maxlen_.

diff --git a/pod/perldelta.pod b/pod/perldelta.pod
index f0f60c5c03..d520a3f668 100644
--- a/pod/perldelta.pod
+++ b/pod/perldelta.pod
@@ -506,6 +506,13 @@ incorrectly truncated.

 =item *

+A regular expression performing a case insensitive match with Unicode
+rules could fail to match correctly when the ability of folding
+characters to both decrease I<minlen> and increase I<maxlen> at the
+same time was not taken into account.
+
+=item *
+
 The offset of a \K is no longer narrowed on rollback at an offset >2GiB.

 =item *
diff --git a/regcomp_trie.c b/regcomp_trie.c
index f3c579ebc9..f1ddafab40 100644
--- a/regcomp_trie.c
+++ b/regcomp_trie.c
@@ -884,11 +884,16 @@ Perl_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
                 trie->minlen = minchars;
                 trie->maxlen = maxchars;
             }
-            else if (minchars < trie->minlen) {
-                trie->minlen = minchars;
-            }
-            else if (maxchars > trie->maxlen) {
-                trie->maxlen = maxchars;
+            else {
+                /* The same piece of a pattern could alter both minlen and maxlen.
+                 * For example, in /(?iu)(?:AASAS|SSASSA.../
+                 *     AASAS first gives us minlen == maxlen == 5
+                 *     SSASSA could be 4, 5, or 6 characters, so minlen drops to
+                 *         4 and maxlen increases to 6. */
+                if (minchars < trie->minlen)
+                    trie->minlen = minchars;
+                if (maxchars > trie->maxlen)
+                    trie->maxlen = maxchars;
             }
             {
                 U32 dupe = trie->states[state].wordnum;
diff --git a/t/re/re_tests b/t/re/re_tests
index 2be484c8cf..b313b83552 100644
--- a/t/re/re_tests
+++ b/t/re/re_tests
@@ -2372,6 +2372,8 @@ a+X(*COMMIT)j	aXaXj	n	-	-	-	PLUS skip after (*COMMIT) [ASCII]
 /^\ba*\z/m	a	y	$&	a	-	MBOL and BOUND start class should match
 /\A^\ba*\z/m	a	y	$&	a	-	MBOL and SBOL and BOUND start class should match

+(?iu)(?:AASAS|SSASSA|AA|SSS)	SSASSAAK	y	$&	SSASSA	-	same pre-TRIE node modifies minlen & maxlen
+
 # Keep these lines at the end of the file
 # pat	string	y/n/etc	expr	expected-expr	skip-reason	comment
 # vim: softtabstop=0 noexpandtab