diff options
author | Zefram <zefram@fysh.org> | 2018-02-15 18:21:14 +0000 |
---|---|---|
committer | Zefram <zefram@fysh.org> | 2018-02-15 18:21:14 +0000 |
commit | 682f3ac7d3c98fe1aa251a2e30684eeb7b859a0e (patch) | |
tree | 37121974a418ab033bf46afec07b12521ec88b02 /dist/Carp | |
parent | 599926360f3b0336743acf167763375ab7f79d41 (diff) | |
download | perl-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.pm | 18 | ||||
-rw-r--r-- | dist/Carp/lib/Carp/Heavy.pm | 2 | ||||
-rw-r--r-- | dist/Carp/t/vivify_stash.t | 8 |
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; |