This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #82854] utf8, $SIG{__DIE__}, syntax errors and Carp
authorFather Chrysostomos <sprout@cpan.org>
Tue, 8 Feb 2011 00:49:38 +0000 (16:49 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Tue, 8 Feb 2011 00:53:37 +0000 (16:53 -0800)
If a syntax error has occurred, module loading causes the ‘BEGIN not
safe after errors’ error.

As of perl 5.12.0 (commit 7d0994e05, actually), error messages men-
tioning variable names that originate from ‘use utf8’ scopes and are
passed to __DIE__ handlers correctly have the UTF8 flag turned on, so
that a variable named $ġ will actually cause the error message to con-
tain ‘$ġ’, rather than ‘$Ä¡’. (As a side effect, even if the variable
does not contain non-ASCII characters, the error message still gets
the UTF8 flag turned on.)

Carp was using a \d in a regular expression against the error message.

\d loads Unicode tables if the LHS has the UTF8 flag turned on.

This means that this snippet:

use utf8;
use strict;
use CGI::Carp 'fatalsToBrowser';
$c;

dies with ‘BEGIN not safe...’, because the error message that triggers
it is ‘Global symbol "$c" requires explicit package name’, it has the
UTF8 flag turned on, CGI::Carp passes it to Carp.pm, Carp tries to do
a /\d/ match against it and \d tries to load Unicode tables, dying
with ‘BEGIN not safe...‘.

This commit just changes the \d in Carp.pm to [0-9], since that is
what was intended anyway.

lib/Carp.pm
lib/Carp.t

index be4cb69..77fc2a1 100644 (file)
@@ -146,9 +146,9 @@ sub format_arg {
         $arg = str_len_trim( $arg, $MaxArgLen );
 
         # Quote it?
-        $arg = "'$arg'" unless $arg =~ /^-?[\d.]+\z/;
-    }
-    else {
+        $arg = "'$arg'" unless $arg =~ /^-?[0-9.]+\z/;
+    }                                    # 0-9, not \d, as \d will try to
+    else {                               # load Unicode tables
         $arg = 'undef';
     }
 
index 9a785f5..b9997cc 100644 (file)
@@ -12,7 +12,7 @@ my $Is_VMS = $^O eq 'VMS';
 use Carp qw(carp cluck croak confess);
 
 BEGIN {
-    plan tests => 56;
+    plan tests => 57;
 
     # This test must be run at BEGIN time, because code later in this file
     # sets CORE::GLOBAL::caller
@@ -377,6 +377,19 @@ like(
     'Correct arguments for A'
 );
 
+# UTF8-flagged strings should not cause Carp to try to load modules (even
+# implicitly via utf8_heavy.pl) after a syntax error [perl #82854].
+fresh_perl_like(
+ q<
+   use utf8; use strict; use Carp;
+   BEGIN { $SIG{__DIE__} = sub { Carp::croak "aaaaa$_[0]" } }
+   $c
+  >,
+ qr/aaaaa/,
+ {stderr=>1},
+ 'Carp can handle UTF8-flagged strings after a syntax error',
+);
+
 # New tests go here
 
 # line 1 "A"