This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Script Run: Scripts couldn't start with Common
authorKarl Williamson <khw@cpan.org>
Thu, 4 Jan 2018 19:22:26 +0000 (12:22 -0700)
committerKarl Williamson <khw@cpan.org>
Thu, 4 Jan 2018 19:38:51 +0000 (12:38 -0700)
The Common script is supposed to be intermixable with any other script.
But it wasn't properly handling the case where the first character in
the string was Common, and a subsequent character was some real script.

regexec.c
t/re/script_run.t

index 7be4f03..a801d45 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -10228,10 +10228,32 @@ Perl_isSCRIPT_RUN(pTHX_ const U8 * s, const U8 * send, const bool utf8_target)
         }
 
         /* Now we can see if the script of the character is the same as that of
-         * the run, or 'Common' which is considered to be in every script */
-        if (LIKELY(   script_of_char == script_of_run
-                   || script_of_char == SCX_Common))
-        {   /* By far the most common case */
+         * the run */
+        if (LIKELY(script_of_char == script_of_run)) {
+            /* By far the most common case */
+            goto scripts_match;
+        }
+
+        /* Here, the scripts of the run and the current character don't match
+         * exactly.  The run could so far have been entirely characters from
+         * Common.  It's now time to change its script to that of this
+         * non-Common character */
+        if (script_of_run == SCX_Common) {
+
+            /* But Common contains several sets of digits.  Only the '0' set
+             * can be part of another script. */
+            if (zero_of_run > 0 && zero_of_run != '0') {
+                retval = FALSE;
+                break;
+            }
+
+            script_of_run = script_of_char;
+            goto scripts_match;
+        }
+
+        /* Here, the script of the run isn't Common.  But characters in Common
+         * match any script */
+        if (script_of_char == SCX_Common) {
             goto scripts_match;
         }
 
index 7cb4d52..318e125 100644 (file)
@@ -40,6 +40,7 @@ like("\N{ARABIC-INDIC DIGIT ZERO}\N{ARABIC-INDIC DIGIT ONE}\N{ARABIC-INDIC DIGIT
 # writing (U+02B9/02BA).
 like("abc\N{MODIFIER LETTER SMALL Y}", $script_run, "All Latin is a script run");
 like("abc\N{MODIFIER LETTER PRIME}", $script_run, "Latin then Common is a script run");
+like(":a", $script_run, "Common then Latin is a script run");
 like("\N{HEBREW LETTER ALEF}\N{HEBREW LETTER TAV}\N{MODIFIER LETTER PRIME}", $script_run, "Hebrew then Common is a script run");
 unlike("\N{HEBREW LETTER ALEF}\N{HEBREW LETTER TAV}\N{MODIFIER LETTER SMALL Y}", $script_run, "Hebrew then Latin isn't a script run");
 like("9876543210\N{DESERET SMALL LETTER WU}", $script_run, "0-9 are the digits for Deseret");