Skip to content

Commit 39e539e

Browse files
committed
Fix uniqint SIGSEGV for objects with no int overload
In case uniqint takes several objects, it always tries to call their int overload using amagic_call. This patch fixes the case when amagic_call returned NULL resulting into Segmentation Violation. Several tests are also added to ensure proper objects handling. Signed-off-by: Sergei Zhmylev <[email protected]>
1 parent 3941392 commit 39e539e

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

ListUtil.xs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1369,8 +1369,10 @@ CODE:
13691369
/* coerce to integer */
13701370
#if PERL_VERSION >= 8
13711371
/* int_amg only appeared in perl 5.8.0 */
1372-
if(SvAMAGIC(arg) && (arg = AMG_CALLun(arg, int)))
1373-
; /* nothing to do */
1372+
if(SvAMAGIC(arg)) {
1373+
if(!(arg = AMG_CALLun(arg, int)))
1374+
croak("No \"int\" method found in overloaded package");
1375+
}
13741376
else
13751377
#endif
13761378
if(!SvOK(arg) || SvNOK(arg) || SvPOK(arg))

t/uniq.t

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use strict;
44
use warnings;
55
use Config; # to determine ivsize
6-
use Test::More tests => 31;
6+
use Test::More tests => 35;
77
use List::Util qw( uniqstr uniqint uniq );
88

99
use Tie::Array;
@@ -98,6 +98,32 @@ is_deeply( [ uniqint 6.1, 6.2, 6.3 ],
9898
'uniqint on undef coerces to zero' );
9999
}
100100

101+
{
102+
use Math::BigInt;
103+
my ($obj1, $obj2, $obj3) = map { Math::BigInt->new($_) } 1, 1, 2;
104+
105+
is_deeply( [ uniqint $obj1, $obj1 ],
106+
[ $obj1 ],
107+
'uniqint removes repeated Math::BigInt objects' );
108+
109+
is_deeply( [ uniqint $obj1, $obj2 ],
110+
[ $obj1 ],
111+
'uniqint removes subsequent Math::BigInt objects' );
112+
113+
is_deeply( [ uniqint $obj1, $obj2, $obj3 ],
114+
[ $obj1, $obj3 ],
115+
'uniqint removes multiple subsequent Math::BigInt objects' );
116+
}
117+
118+
{
119+
{ package OverloadedPackageWithoutInt; use overload "+" => sub {} }
120+
121+
my $obj1 = bless {}, "OverloadedPackageWithoutInt";
122+
123+
ok( !defined eval { uniqint $obj1 },
124+
'package with no "int" overload throws exception' );
125+
}
126+
101127
SKIP: {
102128
skip('UVs are not reliable on this perl version', 2) unless "$]" >= 5.008000;
103129

0 commit comments

Comments
 (0)