This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
regcomp.c: Under /l any < 256 char can match any other
authorKarl Williamson <khw@cpan.org>
Mon, 4 Feb 2019 16:18:24 +0000 (09:18 -0700)
committerKarl Williamson <khw@cpan.org>
Tue, 5 Feb 2019 18:44:29 +0000 (11:44 -0700)
The code knew this, but it was adding the ASCII alphabetics to the list
of things that matched in UTF-8 locales.  This is unnecessary, as we've
long had the infrastructure elsewhere to handle all potential mappings
from a Latin1 code point to other Latin1, so we can just rely on it.
And it created complexities for future commits in this series.

The MICRO SIGN is the exception, as it folds to non-Latin1 in UTF-8
locales, and this is the place where the structure exists to handle
that.

regcomp.c
t/re/anyof.t

index 4fa1224..547398f 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -17827,8 +17827,10 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth,
 
             /* Our calculated list will be for Unicode rules.  For locale
              * matching, we have to keep a separate list that is consulted at
-             * runtime only when the locale indicates Unicode rules.  For
-             * non-locale, we just use the general list */
+             * runtime only when the locale indicates Unicode rules (and we
+             * don't include potential matches in the ASCII/Latin1 range, as
+             * any code point could fold to any other, based on the run-time
+             * locale).   For non-locale, we just use the general list */
             if (LOC) {
                 use_list = &only_utf8_locale_list;
             }
@@ -17860,7 +17862,16 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth,
 
                     if (j < 256) {
 
-                        if (IS_IN_SOME_FOLD_L1(j)) {
+                        /* Under /l, we don't know what code points below 256
+                         * fold to, except we do know the MICRO SIGN folds to
+                         * an above-255 character if the locale is UTF-8, so we
+                         * add it to the special list (in *use_list)  Otherwise
+                         * we know now what things can match, though some folds
+                         * are valid under /d only if the target is UTF-8.
+                         * Those go in a separate list */
+                        if (      IS_IN_SOME_FOLD_L1(j)
+                            && ! (LOC && j != MICRO_SIGN))
+                        {
 
                             /* ASCII is always matched; non-ASCII is matched
                              * only under Unicode rules (which could happen
index 32e0bae..116c238 100644 (file)
@@ -462,7 +462,7 @@ my @tests = (
     '(?l:[\x{212A}])' => 'ANYOFL[212A]',
     '(?l:[\s\x{212A}])' => 'ANYOFPOSIXL[\s][1680 2000-200A 2028-2029 202F 205F 212A 3000]',
     '(?l:[^\S\x{202F}])' => 'ANYOFPOSIXL[^\\S][1680 2000-200A 2028-2029 205F 3000]',
-    '(?li:[a-z])' => 'ANYOFL{i}[a-z{utf8 locale}A-Z\x{017F}\x{212A}]',
+    '(?li:[a-z])' => 'ANYOFL{i}[a-z{utf8 locale}\x{017F}\x{212A}]',
 
     '\p{All}' => 'SANY',
     '\P{All}' => 'OPFAIL',