From: Father Chrysostomos Date: Tue, 5 Oct 2010 06:04:44 +0000 (-0700) Subject: [perl #73534] Bigrat segfaults on irrational numbers X-Git-Tag: v5.13.6~249 X-Git-Url: https://perl5.git.perl.org/perl5.git/commitdiff_plain/45029d2dbcc918ee10234beaf6a38744ad61567e [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)' --- diff --git a/MANIFEST b/MANIFEST index a773176..6ab6a86 100644 --- a/MANIFEST +++ b/MANIFEST @@ -2825,6 +2825,7 @@ dist/Math-BigInt/t/sub_mbf.t Empty subclass test of BigFloat dist/Math-BigInt/t/sub_mbi.t Empty subclass test of BigInt dist/Math-BigInt/t/sub_mif.t Test A & P with subclasses using mbimbf.inc dist/Math-BigInt/t/trap.t Test whether trap_nan and trap_inf work +dist/Math-BigInt/t/upgrade2.t Test that two upgrade levels work dist/Math-BigInt/t/upgradef.t Test if use Math::BigFloat(); under upgrade works dist/Math-BigInt/t/upgrade.inc Actual tests for upgrade.t dist/Math-BigInt/t/upgrade.t Test if use Math::BigInt(); under upgrade works diff --git a/dist/Math-BigInt/lib/Math/BigInt.pm b/dist/Math-BigInt/lib/Math/BigInt.pm index aa26996..0ab9120 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 0000000..cdc8d0e --- /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'); diff --git a/pod/perldelta.pod b/pod/perldelta.pod index 74a1082..b478273 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -258,7 +258,10 @@ messages are not supressed =item * -C has been upgraded from version 1.95 to 1.96. +C has been upgraded from version 1.95 to 1.97. + +This prevents C from crashing under C +L<[perl #73534]|http://rt.perl.org/rt3//Public/Bug/Display.html?id=73534>. =item *