diff options
author | Father Chrysostomos <sprout@cpan.org> | 2010-10-04 23:04:44 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2010-10-04 23:05:59 -0700 |
commit | 45029d2dbcc918ee10234beaf6a38744ad61567e (patch) | |
tree | da5557fd6d5b48c27ccf793368418a27265b782c /dist/Math-BigInt | |
parent | 733a5566738583595dfc3a5d95e1229a3bfda72f (diff) | |
download | perl-45029d2dbcc918ee10234beaf6a38744ad61567e.tar.gz |
[perl #73534] Bigrat segfaults on irrational numbers
aka [rt.cpan.org #55767] segfault on sqrt(2) with bigrat
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)'
Diffstat (limited to 'dist/Math-BigInt')
-rw-r--r-- | dist/Math-BigInt/lib/Math/BigInt.pm | 4 | ||||
-rw-r--r-- | dist/Math-BigInt/t/upgrade2.t | 14 |
2 files changed, 16 insertions, 2 deletions
diff --git a/dist/Math-BigInt/lib/Math/BigInt.pm b/dist/Math-BigInt/lib/Math/BigInt.pm index aa26996153..0ab9120b70 100644 --- a/dist/Math-BigInt/lib/Math/BigInt.pm +++ b/dist/Math-BigInt/lib/Math/BigInt.pm @@ -18,7 +18,7 @@ package Math::BigInt; my $class = "Math::BigInt"; use 5.006002; -$VERSION = '1.96'; +$VERSION = '1.97'; @ISA = qw(Exporter); @EXPORT_OK = qw(objectify bgcd blcm); @@ -2559,7 +2559,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); diff --git a/dist/Math-BigInt/t/upgrade2.t b/dist/Math-BigInt/t/upgrade2.t new file mode 100644 index 0000000000..cdc8d0edf4 --- /dev/null +++ b/dist/Math-BigInt/t/upgrade2.t @@ -0,0 +1,14 @@ +#!/usr/bin/perl -w + +# Test 2 levels of upgrade classes. This used to cause a segv. + +use Test::More tests => 1; + +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 2 upgrade levels'); |