diff options
author | Yves Orton <demerphq@gmail.com> | 2018-02-24 12:37:29 +0100 |
---|---|---|
committer | Yves Orton <demerphq@gmail.com> | 2018-02-24 13:10:18 +0100 |
commit | 17157c41e6523264e0f5e7d4baa490a1a8f2322b (patch) | |
tree | 09cad3d8a42449bd231635062716907ec1bac7e8 /dist/Carp | |
parent | 6ccface2f73d9f16aa9cd1ac99313b2f822cf150 (diff) | |
download | perl-17157c41e6523264e0f5e7d4baa490a1a8f2322b.tar.gz |
Fix perl #132902 - Carp: avoid infinite loops when checking for overloads
We use $obj->can("((") to see if a package has enabled overloads,
however in some cases can() is overridden with a custom implementation,
which may be unaware of these methods and then call Carp itself. This
then results in an infinite loop. An example is Class::Std v0.013.
While technically this is a bug in whatever overrides UNIVERSAL::can(),
Carp is so prolific in its use that we might as well treat it as a Carp
bug also and avoid the problem outright.
See also: https://github.com/chorny/Class-Std/pull/2
Diffstat (limited to 'dist/Carp')
-rw-r--r-- | dist/Carp/Changes | 24 | ||||
-rw-r--r-- | dist/Carp/lib/Carp.pm | 31 | ||||
-rw-r--r-- | dist/Carp/lib/Carp/Heavy.pm | 2 |
3 files changed, 43 insertions, 14 deletions
diff --git a/dist/Carp/Changes b/dist/Carp/Changes index c0f378cbf9..db3920329b 100644 --- a/dist/Carp/Changes +++ b/dist/Carp/Changes @@ -1,3 +1,27 @@ +version 1.48 + + * guard against hand-rolled UNIVERSAL::can() implementations + which throw exceptions when we call $obj->can("(("). + +version 1.47, 1.47_02 + + * Deal with overloading when overload.pm is not use + + * Note 1.47_02 only existed for one commit in blead-perl, + and in fact no 1.47 should ever see the wild. + +version 1.47, 1.47_01 + + * Do not die on trappable stack-not-refcounted bugs while + serializing the stack. + + * Note 1.47_01 only existed for one commit in blead-perl, + and in fact no 1.47 should ever see the wild. + +version 1.46 + + * avoid vivifying UNIVERSAL::isa:: in Carp + version 1.45 * Optimize format_arg when arguments contain many references diff --git a/dist/Carp/lib/Carp.pm b/dist/Carp/lib/Carp.pm index 3de78d9f6f..9956f128d1 100644 --- a/dist/Carp/lib/Carp.pm +++ b/dist/Carp/lib/Carp.pm @@ -116,7 +116,7 @@ BEGIN { ; } -our $VERSION = '1.47'; +our $VERSION = '1.48'; $VERSION =~ tr/_//d; our $MaxEvalLen = 0; @@ -336,18 +336,23 @@ sub format_arg { } else { - if ($pack->can("((")) { - # Argument is blessed into a class with overloading, and - # so might have an overloaded stringification. We don't - # want to risk getting the overloaded stringification, - # so we need to use overload::StrVal() below. But it's - # possible that the overload module hasn't been loaded: - # overload methods can be installed without it. So load - # the module here. The bareword form of require is here - # eschewed to avoid iths compile-time effect of vivifying - # vivifying the target module's stash. - require "overload.pm" - or return "use overload failed"; + # overload uses the presence of a special "method" name "((" to signal + # it is in effect. This test seeks to see if it has been set up. + # In theory we should be able to use 'can' without the $in_recurse guard, + # but this breaks modules that call overloads or croak during can(), for + # instance Class::Std v0.013, so if we end up here twice, we will just + # load overload outright. + if ($in_recurse || do{ local $in_recurse = 1; $pack->can("((") }) { + # Argument is blessed into a class with overloading, and + # so might have an overloaded stringification. We don't + # want to risk getting the overloaded stringification, + # so we need to use overload::StrVal() below. But it's + # possible that the overload module hasn't been loaded: + # overload methods can be installed without it. So load + # the module here. The bareword form of require is here + # eschewed to avoid this compile-time effect of vivifying + # the target module's stash. + require "overload.pm"; } my $sub = _fetch_sub(overload => 'StrVal'); return $sub ? &$sub($arg) : "$arg"; diff --git a/dist/Carp/lib/Carp/Heavy.pm b/dist/Carp/lib/Carp/Heavy.pm index a82325f4ce..5188f40d0e 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.47'; +our $VERSION = '1.48'; $VERSION =~ tr/_//d; # Carp::Heavy was merged into Carp in version 1.12. Any mismatched versions |