This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #129164] Crash with splice
authorFather Chrysostomos <sprout@cpan.org>
Mon, 12 Sep 2016 04:29:56 +0000 (21:29 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Mon, 12 Sep 2016 04:30:10 +0000 (21:30 -0700)
This fixes #129166 and #129167 as well.

splice needs to take into account that arrays can hold NULLs and
return &PL_sv_undef in those cases where it would have returned a
NULL element.

pp.c
t/op/array.t

diff --git a/pp.c b/pp.c
index 49b6abe..ea49b01 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -5363,6 +5363,8 @@ PP(pp_splice)
                for (i = length - 1, dst = &AvARRAY(ary)[offset]; i > 0; i--)
                    SvREFCNT_dec(*dst++);       /* free them now */
            }
                for (i = length - 1, dst = &AvARRAY(ary)[offset]; i > 0; i--)
                    SvREFCNT_dec(*dst++);       /* free them now */
            }
+           if (!*MARK)
+               *MARK = &PL_sv_undef;
        }
        AvFILLp(ary) += diff;
 
        }
        AvFILLp(ary) += diff;
 
@@ -5459,6 +5461,8 @@ PP(pp_splice)
                while (length-- > 0)
                    SvREFCNT_dec(tmparyval[length]);
            }
                while (length-- > 0)
                    SvREFCNT_dec(tmparyval[length]);
            }
+           if (!*MARK)
+               *MARK = &PL_sv_undef;
        }
        else
            *MARK = &PL_sv_undef;
        }
        else
            *MARK = &PL_sv_undef;
index 691d6ce..59ba434 100644 (file)
@@ -558,4 +558,21 @@ is $#foo, 3, 'assigning to arylen aliased in foreach(scalar $#arylen)';
 sub { undef *_; shift }->(); # This would crash; no ok() necessary.
 sub { undef *_; pop   }->();
 
 sub { undef *_; shift }->(); # This would crash; no ok() necessary.
 sub { undef *_; pop   }->();
 
+# [perl #129164], [perl #129166], [perl #129167]
+# splice() with null array entries
+# These used to crash.
+$#a = -1; $#a++;
+() = 0-splice @a; # subtract
+$#a = -1; $#a++;
+() =  -splice @a; # negate
+$#a = -1; $#a++;
+() = 0+splice @a; # add
+# And with array expansion, too
+$#a = -1; $#a++;
+() = 0-splice @a, 0, 1, 1, 1;
+$#a = -1; $#a++;
+() =  -splice @a, 0, 1, 1, 1;
+$#a = -1; $#a++;
+() = 0+splice @a, 0, 1, 1, 1;
+
 "We're included by lib/Tie/Array/std.t so we need to return something true";
 "We're included by lib/Tie/Array/std.t so we need to return something true";