Skip Menu |

This queue is for tickets about the Scalar-List-Utils CPAN distribution.

Report information
The Basics
Id: 39144
Status: resolved
Priority: 0/
Queue: Scalar-List-Utils

People
Owner: Nobody in particular
Requestors: mschwern [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 1.19
Fixed in: (no value)



Subject: [PATCH] Pure Perl blessed() with no UNIVERSAL method.
Attached is an implementation of pure Perl blessed() that does not pollute UNIVERSAL. It even works when isa() and can() are broken.
Subject: blessed.patch
--- Scalar-List-Utils-1.19/lib/Scalar/Util.pm 2006-12-10 08:03:45.000000000 -0800 +++ Scalar-List-Utils-1.19.new/lib/Scalar/Util.pm 2008-09-09 16:38:24.000000000 -0700 @@ -58,14 +58,10 @@ # The code beyond here is only used if the XS is not installed -# Hope nobody defines a sub by this name -sub UNIVERSAL::a_sub_not_likely_to_be_here { ref($_[0]) } - sub blessed ($) { local($@, $SIG{__DIE__}, $SIG{__WARN__}); - length(ref($_[0])) - ? eval { $_[0]->a_sub_not_likely_to_be_here } - : undef + return undef unless length(ref($_[0])); + return eval { UNIVERSAL::isa($_[0], "UNIVERSAL"); } ? ref($_[0]) : undef; } sub refaddr($) { @@ -89,8 +85,7 @@ length($t = ref($r)) or return undef; - # This eval will fail if the reference is not blessed - eval { $r->a_sub_not_likely_to_be_here; 1 } + defined blessed($r) ? do { $t = eval { # we have a GLOB or an IO. Stringify a GLOB gives it's name --- Scalar-List-Utils-1.19/t/blessed.t 2006-12-10 08:03:45.000000000 -0800 +++ Scalar-List-Utils-1.19.new/t/blessed.t 2008-09-09 16:35:15.000000000 -0700 @@ -13,7 +13,7 @@ } } -use Test::More tests => 8; +use Test::More tests => 9; use Scalar::Util qw(blessed); use vars qw($t $x); @@ -29,3 +29,12 @@ $x = bless {}, "DEF"; is(blessed($x), "DEF", 'blessed HASH-ref'); + +{ + package Broken; + sub isa { die }; + sub can { die }; + + my $obj = bless [], __PACKAGE__; + ::is( ::blessed($obj), __PACKAGE__, "blessed on broken isa() and can()" ); +}
Subject: Re: [rt.cpan.org #39144] [PATCH] Pure Perl blessed() with no UNIVERSAL method.
Date: Wed, 10 Sep 2008 14:05:46 -0500
To: bug-Scalar-List-Utils [...] rt.cpan.org
From: Graham Barr <gbarr [...] pobox.com>
Thanks for the patch. I have already made a change to this sub which will look like this in the next release sub blessed ($) { local($@, $SIG{__DIE__}, $SIG{__WARN__}); length(ref($_[0])) ? eval { $_[0]->UNIVERSAL::can('can') && ref($_[0]) } : undef; } It has been a while since the last release so I am working back through a lot of stuff. Where I am right now you can see at http://git.goingon.net/?p=Scalar-List-Utils.git;a=shortlog;h=refs/heads/next Graham.
Subject: Re: [rt.cpan.org #39144] [PATCH] Pure Perl blessed() with no UNIVERSAL method.
Date: Wed, 10 Sep 2008 14:04:22 -0700
To: bug-Scalar-List-Utils [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Graham Barr via RT wrote: Show quoted text
> <URL: http://rt.cpan.org/Ticket/Display.html?id=39144 > > > Thanks for the patch. I have already made a change to this sub which > will look like this in the next release > > sub blessed ($) { > local($@, $SIG{__DIE__}, $SIG{__WARN__}); > length(ref($_[0])) > ? eval { $_[0]->UNIVERSAL::can('can') && ref($_[0]) } > : undef; > }
Excellent. Might want to patch in the extra blessed.t test for a broken can() and isa() as my first naive implementation using $_[0]->isa() passed. Show quoted text
> It has been a while since the last release so I am working back > through a lot of stuff. Where I am right now you can see at > > http://git.goingon.net/?p=Scalar-List-Utils.git;a=shortlog;h=refs/heads/next
You're using git, too. -- Life is like a sewer - what you get out of it depends on what you put into it. - Tom Lehrer
Subject: Re: [rt.cpan.org #39144] [PATCH] Pure Perl blessed() with no UNIVERSAL method.
Date: Wed, 10 Sep 2008 17:28:36 -0500
To: bug-Scalar-List-Utils [...] rt.cpan.org
From: Graham Barr <gbarr [...] pobox.com>
On Sep 10, 2008, at 4:04 PM, Michael G Schwern via RT wrote: Show quoted text
> Queue: Scalar-List-Utils > Ticket <URL: http://rt.cpan.org/Ticket/Display.html?id=39144 > > > Graham Barr via RT wrote:
>> <URL: http://rt.cpan.org/Ticket/Display.html?id=39144 > >> >> Thanks for the patch. I have already made a change to this sub which >> will look like this in the next release >> >> sub blessed ($) { >> local($@, $SIG{__DIE__}, $SIG{__WARN__}); >> length(ref($_[0])) >> ? eval { $_[0]->UNIVERSAL::can('can') && ref($_[0]) } >> : undef; >> }
> > Excellent. Might want to patch in the extra blessed.t test for a > broken can() > and isa() as my first naive implementation using $_[0]->isa() passed.
But I do not use ->can it uses ->UNIVERSAL::can which is no different to calling UNIVERSAL::can($_[0],'can'), but I will add it Of course it still can fail if someone redefined UNIVERSAL::can Show quoted text
>> It has been a while since the last release so I am working back >> through a lot of stuff. Where I am right now you can see at >> >> http://git.goingon.net/?p=Scalar-List-Utils.git;a=shortlog;h=refs/heads/next
> > You're using git, too.
Yes, switched from svn a while back. Graham.
Subject: Re: [rt.cpan.org #39144] [PATCH] Pure Perl blessed() with no UNIVERSAL method.
Date: Wed, 10 Sep 2008 16:06:56 -0700
To: bug-Scalar-List-Utils [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Graham Barr via RT wrote: Show quoted text
>> Excellent. Might want to patch in the extra blessed.t test for a >> broken can() >> and isa() as my first naive implementation using $_[0]->isa() passed.
> > But I do not use ->can it uses ->UNIVERSAL::can which is no different > to calling UNIVERSAL::can($_[0],'can'), but I will add it
Right. The test is to make sure someone in the future doesn't come along and go "Oh ho! Someone's calling UNIVERSAL::can() directly and that's naughty! I'll just fix that..." Show quoted text
> Of course it still can fail if someone redefined UNIVERSAL::can
HAHA! Why would somebody do something as silly as th- $ perl -w -Mblib -MUNIVERSAL::can t/p_blessed.t 1..9 ok 1 - undef is not blessed ok 2 - Numbers are not blessed ok 3 - Strings are not blessed ok 4 - Unblessed HASH-ref ok 5 - Unblessed ARRAY-ref ok 6 - Unblessed SCALAR-ref ok 7 - blessed ARRAY-ref ok 8 - blessed HASH-ref Deep recursion on subroutine "Scalar::Util::blessed" at /usr/local/lib/site_perl/UNIVERSAL/can.pm line 82. Deep recursion on subroutine "UNIVERSAL::can::can" at (eval 7) line 10. Deep recursion on subroutine "UNIVERSAL::can::_is_invocant" at /usr/local/lib/site_perl/UNIVERSAL/can.pm line 52. God damn it. Seems both UNIVERSAL::isa and UNIVERSAL::can use blessed(). -- 87. If the thought of something makes me giggle for longer than 15 seconds, I am to assume that I am not allowed to do it. -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army http://skippyslist.com/list/
Subject: Re: [rt.cpan.org #39144] [PATCH] Pure Perl blessed() with no UNIVERSAL method.
Date: Wed, 10 Sep 2008 18:31:41 -0500
To: bug-Scalar-List-Utils [...] rt.cpan.org
From: Graham Barr <gbarr [...] pobox.com>
On Sep 10, 2008, at 6:07 PM, Michael G Schwern via RT wrote: Show quoted text
>> Of course it still can fail if someone redefined UNIVERSAL::can
> > HAHA! Why would somebody do something as silly as th- > > $ perl -w -Mblib -MUNIVERSAL::can t/p_blessed.t > 1..9 > ok 1 - undef is not blessed > ok 2 - Numbers are not blessed > ok 3 - Strings are not blessed > ok 4 - Unblessed HASH-ref > ok 5 - Unblessed ARRAY-ref > ok 6 - Unblessed SCALAR-ref > ok 7 - blessed ARRAY-ref > ok 8 - blessed HASH-ref > Deep recursion on subroutine "Scalar::Util::blessed" at > /usr/local/lib/site_perl/UNIVERSAL/can.pm line 82. > Deep recursion on subroutine "UNIVERSAL::can::can" at (eval 7) line > 10. > Deep recursion on subroutine "UNIVERSAL::can::_is_invocant" at > /usr/local/lib/site_perl/UNIVERSAL/can.pm line 52. > > God damn it. > > Seems both UNIVERSAL::isa and UNIVERSAL::can use blessed().
But that is a bug in their code, IMO They both have code to prevent recursing, but it does not protect enough Graham.
Subject: Re: [rt.cpan.org #39144] [PATCH] Pure Perl blessed() with no UNIVERSAL method.
Date: Wed, 10 Sep 2008 19:06:17 -0500
To: bug-Scalar-List-Utils [...] rt.cpan.org
From: Graham Barr <gbarr [...] pobox.com>
Show quoted text
> Deep recursion on subroutine "Scalar::Util::blessed" at > /usr/local/lib/site_perl/UNIVERSAL/can.pm line 82. > Deep recursion on subroutine "UNIVERSAL::can::can" at (eval 7) line > 10. > Deep recursion on subroutine "UNIVERSAL::can::_is_invocant" at > /usr/local/lib/site_perl/UNIVERSAL/can.pm line 52.
I added a fix to protect again this. It is a local $recurse check, but it is only in the perl-only code that this is an issue anyway http://git.goingon.net/?p=Scalar-List-Utils.git;a=shortlog;h=refs/heads/next Graham.
Subject: Re: [rt.cpan.org #39144] [PATCH] Pure Perl blessed() with no UNIVERSAL method.
Date: Wed, 10 Sep 2008 18:31:41 -0500
To: bug-Scalar-List-Utils [...] rt.cpan.org
From: Graham Barr <gbarr [...] pobox.com>
On Sep 10, 2008, at 6:07 PM, Michael G Schwern via RT wrote: Show quoted text
>> Of course it still can fail if someone redefined UNIVERSAL::can
> > HAHA! Why would somebody do something as silly as th- > > $ perl -w -Mblib -MUNIVERSAL::can t/p_blessed.t > 1..9 > ok 1 - undef is not blessed > ok 2 - Numbers are not blessed > ok 3 - Strings are not blessed > ok 4 - Unblessed HASH-ref > ok 5 - Unblessed ARRAY-ref > ok 6 - Unblessed SCALAR-ref > ok 7 - blessed ARRAY-ref > ok 8 - blessed HASH-ref > Deep recursion on subroutine "Scalar::Util::blessed" at > /usr/local/lib/site_perl/UNIVERSAL/can.pm line 82. > Deep recursion on subroutine "UNIVERSAL::can::can" at (eval 7) line > 10. > Deep recursion on subroutine "UNIVERSAL::can::_is_invocant" at > /usr/local/lib/site_perl/UNIVERSAL/can.pm line 52. > > God damn it. > > Seems both UNIVERSAL::isa and UNIVERSAL::can use blessed().
But that is a bug in their code, IMO They both have code to prevent recursing, but it does not protect enough Graham.
Subject: Re: [rt.cpan.org #39144] [PATCH] Pure Perl blessed() with no UNIVERSAL method.
Date: Thu, 11 Sep 2008 04:08:51 -0700
To: bug-Scalar-List-Utils [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Graham Barr via RT wrote: Show quoted text
> <URL: http://rt.cpan.org/Ticket/Display.html?id=39144 > >
>> Deep recursion on subroutine "Scalar::Util::blessed" at >> /usr/local/lib/site_perl/UNIVERSAL/can.pm line 82. >> Deep recursion on subroutine "UNIVERSAL::can::can" at (eval 7) line >> 10. >> Deep recursion on subroutine "UNIVERSAL::can::_is_invocant" at >> /usr/local/lib/site_perl/UNIVERSAL/can.pm line 52.
> > I added a fix to protect again this. It is a local $recurse check, but > it is only > in the perl-only code that this is an issue anyway > > http://git.goingon.net/?p=Scalar-List-Utils.git;a=shortlog;h=refs/heads/next
Looks good to me. -- s7ank: i want to be one of those guys that types "s/j&jd//.^$ueu*///djsls/sm." and it's a perl script that turns dog crap into gold.
Fixed in Scalar-List-Utils-1.20