Skip Menu |

This queue is for tickets about the Math-BigInt CPAN distribution.

Report information
The Basics
Id: 55767
Status: resolved
Priority: 0/
Queue: Math-BigInt

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

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



Subject: segfault on sqrt(2) with bigrat
The following command produces a seg fault: tony@mars:~$ perl -Mbigrat -e 'sqrt(2)' Segmentation fault while: tony@mars:~$ perl -Mbigrat -e 'sqrt(2.0)' doesn't. This has been reported as a bug in perl http://rt.perl.org/rt3/Ticket/Display.html?id=73534 Bigrat segfaults on irrational numbers but from what I can see this is a problem in bignum or Math-BigInt, my notes from [perl #72534]: The problem seems to be that a Math::BigInt object (from the value 2) is being passed Math::BigFloat::bsqrt(). Line 2097 of Math::BigFloat then attempts to copy the mantissa (_m) but since $x isn't a Math::BigFloat it passes undef to the _copy() method. So x at Math::BigInt::FastCalc line 117 is an undef SV, the SvRV() call returns NULL, and av_len() segfaults or fails the assertion. Tony
On Sun Mar 21 21:44:05 2010, TONYC wrote: Show quoted text
> The following command produces a seg fault: > > tony@mars:~$ perl -Mbigrat -e 'sqrt(2)' > Segmentation fault > > while: > > tony@mars:~$ perl -Mbigrat -e 'sqrt(2.0)' > > doesn't. This has been reported as a bug in perl > > http://rt.perl.org/rt3/Ticket/Display.html?id=73534 > Bigrat segfaults on irrational numbers > > but from what I can see this is a problem in bignum or Math-BigInt, my > notes from [perl #72534]: > > The problem seems to be that a Math::BigInt object (from the value 2) > is being passed Math::BigFloat::bsqrt(). > > Line 2097 of Math::BigFloat then attempts to copy the mantissa (_m) > but since $x isn't a Math::BigFloat it passes undef to the _copy() > method. > > So x at Math::BigInt::FastCalc line 117 is an undef SV, the SvRV() > call returns NULL, and av_len() segfaults or fails the assertion.
The problem seems to be in &Math::BigInt::objectify. It doesn’t try to convert the number object into the right class if $upgrade is defined. The attached patch changes it to make sure it belongs to the calling class or to the $upgrade class. Here is a ‘one’-liner to trigger the same bug without bigrat: perl -Ilib -MMath::BigInt=upgrade,Math::BigFloat -MMath::BigFloat=upgrade,Math::BigMouse -le '@Math::BigMouse::ISA = Math::BigFloat; print sqrt Math::BigInt->new(2)' And here it is as a test. I’m not sure which file it should go in: use Math::BigInt upgrade => 'Math::BigFloat'; use Math::BigFloat upgrade => 'Math::BigMouse'; no warnings 'once'; @Math::BigMouse::ISA = 'Math::BigFloat'; sqrt Math::BigInt->new(2); pass('sqrt on a big int does not segv if there are two levels of upgrade classes');
Subject: open_i9wQ8Wre.txt
diff -Nurp Math-BigInt-1.89-5BsPi2copy/lib/Math/BigInt.pm Math-BigInt-1.89-5BsPi2/lib/Math/BigInt.pm --- Math-BigInt-1.89-5BsPi2copy/lib/Math/BigInt.pm 2010-03-21 18:25:34.000000000 -0700 +++ Math-BigInt-1.89-5BsPi2/lib/Math/BigInt.pm 2010-03-29 06:25:45.000000000 -0700 @@ -2560,7 +2560,7 @@ sub objectify { $k = $a[0]->new($k); } - elsif (!defined $up && ref($k) ne $a[0]) + elsif (ref($k) ne $a[0] and !defined $up || ref $k ne $up) { # foreign object, try to convert to integer $k->can('as_number') ? $k = $k->as_number() : $k = $a[0]->new($k);
On Sun Apr 04 21:29:15 2010, SPROUT wrote: Show quoted text
> On Sun Mar 21 21:44:05 2010, TONYC wrote:
> > The following command produces a seg fault: > > > > tony@mars:~$ perl -Mbigrat -e 'sqrt(2)' > > Segmentation fault > > > > while: > > > > tony@mars:~$ perl -Mbigrat -e 'sqrt(2.0)' > > > > doesn't. This has been reported as a bug in perl > > > > http://rt.perl.org/rt3/Ticket/Display.html?id=73534 > > Bigrat segfaults on irrational numbers > > > > but from what I can see this is a problem in bignum or Math-BigInt,
> my
> > notes from [perl #72534]: > > > > The problem seems to be that a Math::BigInt object (from the value
> 2)
> > is being passed Math::BigFloat::bsqrt(). > > > > Line 2097 of Math::BigFloat then attempts to copy the mantissa (_m) > > but since $x isn't a Math::BigFloat it passes undef to the _copy() > > method. > > > > So x at Math::BigInt::FastCalc line 117 is an undef SV, the SvRV() > > call returns NULL, and av_len() segfaults or fails the assertion.
> > The problem seems to be in &Math::BigInt::objectify. It doesn’t try to > convert the number > object into the right class if $upgrade is defined. The attached patch > changes it to make sure > it belongs to the calling class or to the $upgrade class. > > Here is a ‘one’-liner to trigger the same bug without bigrat: > > perl -Ilib -MMath::BigInt=upgrade,Math::BigFloat > -MMath::BigFloat=upgrade,Math::BigMouse > -le '@Math::BigMouse::ISA = Math::BigFloat; print sqrt Math::BigInt-
> >new(2)'
> > And here it is as a test. I’m not sure which file it should go in: > > use Math::BigInt upgrade => 'Math::BigFloat'; > use Math::BigFloat upgrade => 'Math::BigMouse'; > no warnings 'once'; > @Math::BigMouse::ISA = 'Math::BigFloat'; > sqrt Math::BigInt->new(2); > pass('sqrt on a big int does not segv if there are two levels of > upgrade classes');
Applied to perl.git/blead as 45029d2.
Bug present i versions 1.76 to 1.96. Fixed in version 1.97.