Skip Menu |
 

This queue is for tickets about the UNIVERSAL-can CPAN distribution.

Report information
The Basics
Id: 49580
Status: resolved
Worked: 15 min
Priority: 0/
Queue: UNIVERSAL-can

People
Owner: chromatic [...] cpan.org
Requestors: POSSUM [...] cpan.org
Cc: BOLDRA [...] boldra.org
AdminCc:

Bug Information
Severity: (no value)
Broken in: 1.15
Fixed in: (no value)



Subject: Deep recursion on String Overloaded object [TEST and PATCH]
Download (untitled) / with headers
text/plain 894b
If UNIVERSAL::can is invoked through an overloaded stringification of an object, it causes a Deep recursion, and eventually segfaults (tested on perl 5.10). This seems to be due to UNIVERSAL::can calling UNIVERSAL::isa and UNIVERSAL::isa calling back to UNIVERSAL::can in this circumstance. I am unsure if this bug is related at all to bug #47326 for UNIVERSAL::isa. https://rt.cpan.org/Ticket/Display.html?id=47326 Attached is a test case demonstrating the problem, and a patch for resolving it. My proposed fix is to add local $recursing = 1 before calling $caller- Show quoted text
>isa($_[0]).
The output of the test case, when broken, is as follows: $ perl universal_can_deep_recursion.t 1..1 Deep recursion on anonymous subroutine at /usr/share/perl5/UNIVERSAL/can.pm line 57. Deep recursion on subroutine "UNIVERSAL::can::can" at universal_can_deep_recursion.t line 6. Segmentation fault
Subject: universal_can_deep_recursion.patch
--- lib/UNIVERSAL/can.pm 2009-06-22 16:42:08.000000000 -0400 +++ lib/UNIVERSAL/can.pm 2009-09-09 16:12:06.000000000 -0400 @@ -40,7 +40,7 @@ goto &$orig if $recursing || ( defined $caller && defined $_[0] - && eval { $caller->isa( $_[0] ); } ); + && eval { local $recursing = 1; $caller->isa($_[0]) } ); # call an overridden can() if it exists my $can = eval { $_[0]->$orig('can') || 0 };
Subject: universal_can_deep_recursion.t
#!/usr/bin/perl package Test::Overloaded::String; use strict; use warnings; use overload '""' => sub { $_[0]->can('bar') }; sub new { bless {}, shift } sub bar {1} 1; package main; use strict; use warnings; use Test::More tests => 1; use UNIVERSAL::can; my $foo = Test::Overloaded::String->new; ok "$foo", "Didn't segfault";
I also had this problem, cygwin perl 5.10, and POSSUMS patch works well for me.
The bug also bit me working with Test::MockObject under Perl 5.10.0 on Linux. -Mark
Download (untitled) / with headers
text/plain 216b
I have discovered that my patch does not fix the problem in some cases under perl 5.8.6 (The Deep recursion warning goes away, but it still segfaults). I will attempt to put together a test case when I get a chance.
Download (untitled) / with headers
text/plain 300b
On Sun Nov 01 18:14:55 2009, MGRIMES wrote: Show quoted text
> The bug also bit me working with Test::MockObject under Perl 5.10.0 on > Linux.
indeed, since test::mockobject is using universal::can. the patch fixes the problem for me on 5.10.1 patched in mandriva package, i'd rather have however a fixed release.
Download (untitled) / with headers
text/plain 164b
I'm tentatively marking this as resolved in 1.16. I applied the patches as-is; thank you. If this is reproducible in 5.8.6 or earlier, please feel free to reopen.


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com.