summaryrefslogtreecommitdiff
path: root/dist/Carp
diff options
context:
space:
mode:
authorZefram <zefram@fysh.org>2018-02-15 18:21:14 +0000
committerZefram <zefram@fysh.org>2018-02-15 18:21:14 +0000
commit682f3ac7d3c98fe1aa251a2e30684eeb7b859a0e (patch)
tree37121974a418ab033bf46afec07b12521ec88b02 /dist/Carp
parent599926360f3b0336743acf167763375ab7f79d41 (diff)
downloadperl-682f3ac7d3c98fe1aa251a2e30684eeb7b859a0e.tar.gz
avoid vivifying UNIVERSAL::isa:: in Carp
The test added to Carp by commit 915a6810d3e3198d759f025f85d1fd6f3171dd27 for UNIVERSAL::isa being loaded had the side effect of vivifying the UNIVERSAL::isa stash. Take more care about checking for UNIVERSAL::isa to avoid vivifying it, as for the other checks for things in optional modules. Fixes [perl #132788].
Diffstat (limited to 'dist/Carp')
-rw-r--r--dist/Carp/lib/Carp.pm18
-rw-r--r--dist/Carp/lib/Carp/Heavy.pm2
-rw-r--r--dist/Carp/t/vivify_stash.t8
3 files changed, 22 insertions, 6 deletions
diff --git a/dist/Carp/lib/Carp.pm b/dist/Carp/lib/Carp.pm
index 65d22b1b2b..eb7ad7bb06 100644
--- a/dist/Carp/lib/Carp.pm
+++ b/dist/Carp/lib/Carp.pm
@@ -116,7 +116,7 @@ BEGIN {
;
}
-our $VERSION = '1.45';
+our $VERSION = '1.46';
$VERSION =~ tr/_//d;
our $MaxEvalLen = 0;
@@ -277,6 +277,20 @@ sub caller_info {
return wantarray() ? %call_info : \%call_info;
}
+sub _univisa_loaded {
+ return 0 unless exists($::{"UNIVERSAL::"});
+ for ($::{"UNIVERSAL::"}) {
+ return 0 unless ref \$_ eq "GLOB" && *$_{HASH} && exists $$_{"isa::"};
+ for ($$_{"isa::"}) {
+ return 0 unless ref \$_ eq "GLOB" && *$_{HASH} && exists $$_{"VERSION"};
+ for ($$_{"VERSION"}) {
+ return 0 unless ref \$_ eq "GLOB";
+ return ${*$_{SCALAR}};
+ }
+ }
+ }
+}
+
# Transform an argument to a function into a string.
our $in_recurse;
sub format_arg {
@@ -286,7 +300,7 @@ sub format_arg {
# lazy check if the CPAN module UNIVERSAL::isa is used or not
# if we use a rogue version of UNIVERSAL this would lead to infinite loop
- my $isa = $UNIVERSAL::isa::VERSION ? sub { 1 } : \&UNIVERSAL::isa;
+ my $isa = _univisa_loaded() ? sub { 1 } : _fetch_sub(UNIVERSAL => "isa");
# legitimate, let's not leak it.
if (!$in_recurse && $isa->( $arg, 'UNIVERSAL' ) &&
diff --git a/dist/Carp/lib/Carp/Heavy.pm b/dist/Carp/lib/Carp/Heavy.pm
index 6575c63d84..1d4bab613f 100644
--- a/dist/Carp/lib/Carp/Heavy.pm
+++ b/dist/Carp/lib/Carp/Heavy.pm
@@ -2,7 +2,7 @@ package Carp::Heavy;
use Carp ();
-our $VERSION = '1.45';
+our $VERSION = '1.46';
$VERSION =~ tr/_//d;
# Carp::Heavy was merged into Carp in version 1.12. Any mismatched versions
diff --git a/dist/Carp/t/vivify_stash.t b/dist/Carp/t/vivify_stash.t
index 0ac66d89e0..455aded7c1 100644
--- a/dist/Carp/t/vivify_stash.t
+++ b/dist/Carp/t/vivify_stash.t
@@ -1,8 +1,9 @@
-BEGIN { print "1..5\n"; }
+BEGIN { print "1..6\n"; }
our $has_utf8; BEGIN { $has_utf8 = exists($::{"utf8::"}); }
our $has_overload; BEGIN { $has_overload = exists($::{"overload::"}); }
our $has_B; BEGIN { $has_B = exists($::{"B::"}); }
+our $has_UNIVERSAL_isa; BEGIN { $has_UNIVERSAL_isa = exists($UNIVERSAL::{"isa::"}); }
use Carp;
sub { sub { Carp::longmess("x") }->() }->(\1, "\x{2603}", qr/\x{2603}/);
@@ -10,16 +11,17 @@ sub { sub { Carp::longmess("x") }->() }->(\1, "\x{2603}", qr/\x{2603}/);
print !(exists($::{"utf8::"}) xor $has_utf8) ? "" : "not ", "ok 1\n";
print !(exists($::{"overload::"}) xor $has_overload) ? "" : "not ", "ok 2\n";
print !(exists($::{"B::"}) xor $has_B) ? "" : "not ", "ok 3\n";
+print !(exists($UNIVERSAL::{"isa::"}) xor $has_UNIVERSAL_isa) ? "" : "not ", "ok 4\n";
# Autovivify $::{"overload::"}
() = \$::{"overload::"};
() = \$::{"utf8::"};
eval { sub { Carp::longmess() }->(\1) };
-print $@ eq '' ? "ok 4\n" : "not ok 4\n# $@";
+print $@ eq '' ? "ok 5\n" : "not ok 5\n# $@";
# overload:: glob without hash
undef *{"overload::"};
eval { sub { Carp::longmess() }->(\1) };
-print $@ eq '' ? "ok 5\n" : "not ok 5\n# $@";
+print $@ eq '' ? "ok 6\n" : "not ok 6\n# $@";
1;