From 27a8a9e2a55ccc148582006396a9c35bafa5f0b3 Mon Sep 17 00:00:00 2001 From: David Mitchell Date: Wed, 30 Nov 2016 08:59:01 +0000 Subject: [PATCH] split was leaving PL_sv_undef in unused ary slots MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Petr Pisar: Ported to 5.24.0: commit 71ca73e5fa9639ac33e9f2e74cd0c32288a5040d Author: David Mitchell Date: Wed Nov 30 08:59:01 2016 +0000 split was leaving PL_sv_undef in unused ary slots This: @a = split(/-/,"-"); $a[1] = undef; $a[0] = 0; was giving Modification of a read-only value attempted at foo line 3. This is because: 1) unused slots in AvARRAY between AvFILL and AvMAX should always be null; av_clear(), av_extend() etc do this; while av_store(), if storing to a slot N somewhere between AvFILL and AvMAX, doesn't bother to clear between (AvFILL+1)..(N-1) on the assumption that everyone else plays nicely. 2) pp_split() when splitting directly to an array, sometimes over-splits and has to null out the excess elements; 3) Since perl 5.19.4, unused AV slots are now marked with NULL rather than &PL_sv_undef; 4) pp_split was still using &PL_sv_undef; The fault was with (4), and is easily fixed. Signed-off-by: Petr Písař --- pp.c | 2 +- t/op/split.t | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/pp.c b/pp.c index 4153482..70345ce 100644 --- a/pp.c +++ b/pp.c @@ -6212,7 +6212,7 @@ PP(pp_split) while (iters > 0 && (!TOPs || !SvANY(TOPs) || SvCUR(TOPs) == 0)) { if (TOPs && !make_mortal) sv_2mortal(TOPs); - *SP-- = &PL_sv_undef; + *SP-- = NULL; iters--; } } diff --git a/t/op/split.t b/t/op/split.t index fb73271..b7846a1 100644 --- a/t/op/split.t +++ b/t/op/split.t @@ -7,7 +7,7 @@ BEGIN { set_up_inc('../lib'); } -plan tests => 131; +plan tests => 133; $FS = ':'; @@ -523,3 +523,14 @@ is "@a", '1 2 3', 'assignment to split-to-array (pmtarget/package array)'; } (@{\@a} = split //, "abc") = 1..10; is "@a", '1 2 3', 'assignment to split-to-array (stacked)'; + +# splitting directly to an array wasn't filling unused AvARRAY slots with +# NULL + +{ + my @a; + @a = split(/-/,"-"); + $a[1] = 'b'; + ok eval { $a[0] = 'a'; 1; }, "array split filling AvARRAY: assign 0"; + is "@a", "a b", "array split filling AvARRAY: result"; +} -- 2.7.4