summaryrefslogtreecommitdiff
path: root/dist/Math-BigInt
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2010-10-04 23:04:44 -0700
committerFather Chrysostomos <sprout@cpan.org>2010-10-04 23:05:59 -0700
commit45029d2dbcc918ee10234beaf6a38744ad61567e (patch)
treeda5557fd6d5b48c27ccf793368418a27265b782c /dist/Math-BigInt
parent733a5566738583595dfc3a5d95e1229a3bfda72f (diff)
downloadperl-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.pm4
-rw-r--r--dist/Math-BigInt/t/upgrade2.t14
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');