This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Fix garbage output from ‘my $é’
authorFather Chrysostomos <sprout@cpan.org>
Sat, 13 Dec 2014 20:35:08 +0000 (12:35 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 13 Dec 2014 21:08:01 +0000 (13:08 -0800)
$ echo 'my $é' | iconv -f utf-8 -t iso-8859-1 | ./perl -Ilib -CS
Can't use global $^ÿ\80\8f¿¿¿¿¿¿¿¿¾© in "my" at - line 1, at end of line

In trying to turn the é into a ^X sequence, alloc_my does toCTRL()
(^64) on it, where the character is treated as a signed inte-
ger, i.e., -23 ^ 64, or -87.  In sv_vcatpvfn_flags, it gets
cast to a UV, so it becomes 18446744073709551529 on 64-bit
platforms. Encoded in ‘extended’ UTF8, that becomes
<FF><80><8F><BF><BF><BF><BF><BF><BF><BF><BF><BE><A9> (assuming I cop-
ied and pasted it from less correctly), which only perl recognizes as
chr 18446744073709551529.

We should not be trying to do $^X on non-ASCII characters.

op.c
t/lib/croak/op

diff --git a/op.c b/op.c
index cef99f2..9e32b23 100644 (file)
--- a/op.c
+++ b/op.c
@@ -592,6 +592,7 @@ Perl_allocmy(pTHX_ const char *const name, const STRLEN len, const U32 flags)
          (name[1] == '_' && (*name == '$' || len > 2))))
     {
        if (!(flags & SVf_UTF8 && UTF8_IS_START(name[1]))
+        && isASCII(name[1])
         && (!isPRINT(name[1]) || strchr("\t\n\r\f", name[1]))) {
            yyerror(Perl_form(aTHX_ "Can't use global %c^%c%.*s in \"%s\"",
                              name[0], toCTRL(name[1]), (int)(len - 2), name + 2,
index d85ef73..5652beb 100644 (file)
@@ -11,6 +11,14 @@ EXPECT
 Can't use global $! in "my" at - line 1, near "my $!"
 Execution of - aborted due to compilation errors.
 ########
+# NAME my $<latin1>
+use open ":std", ":utf8";
+eval qq|my \$\xe9;|; # é in Latin-1
+print $@;
+exit 1;
+EXPECT
+Can't use global $é in "my" at (eval 1) line 1, near "my $é"
+########
 # NAME OP_HELEM fields
 package Foo;
 use fields qw(a b);