This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
split ' ', $foo: don't check end byte
authorDavid Mitchell <davem@iabyn.com>
Mon, 26 Dec 2016 12:49:24 +0000 (12:49 +0000)
committerDavid Mitchell <davem@iabyn.com>
Mon, 26 Dec 2016 12:49:24 +0000 (12:49 +0000)
The special-cased code to skip spaces at the start of the string
didn't check that s < strend, so relied on the string being \0-terminated
to work correctly. The introduction of the isSPACE_utf8_safe() macro
showed up this dodgy assumption by causing assert failures in regen.t
under LC_ALL=en_US.UTF-8 PERL_UNICODE="".

pp.c
t/op/split.t

diff --git a/pp.c b/pp.c
index 300d786..c015bfe 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -5794,15 +5794,15 @@ PP(pp_split)
     orig = s;
     if (RX_EXTFLAGS(rx) & RXf_SKIPWHITE) {
        if (do_utf8) {
-           while (isSPACE_utf8_safe(s, strend))
+           while (s < strend && isSPACE_utf8_safe(s, strend))
                s += UTF8SKIP(s);
        }
        else if (get_regex_charset(RX_EXTFLAGS(rx)) == REGEX_LOCALE_CHARSET) {
-           while (isSPACE_LC(*s))
+           while (s < strend && isSPACE_LC(*s))
                s++;
        }
        else {
-           while (isSPACE(*s))
+           while (s < strend && isSPACE(*s))
                s++;
        }
     }
index ceaea00..81c908e 100644 (file)
@@ -7,7 +7,7 @@ BEGIN {
     set_up_inc('../lib');
 }
 
-plan tests => 161;
+plan tests => 162;
 
 $FS = ':';
 
@@ -621,3 +621,11 @@ is "@a", '1 2 3', 'assignment to split-to-array (stacked)';
     ok eval { $a[0] = 'a'; 1; }, "array split filling AvARRAY: assign 0";
     is "@a", "a b", "array split filling AvARRAY: result";
 }
+
+# splitting an empty utf8 string gave an assert failure
+{
+    my $s = "\x{100}";
+    chop $s;
+    my @a = split ' ', $s;
+    is (+@a, 0, "empty utf8 string");
+}