In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/02960b52b40b494fa4f6e1be81db5f3459ab91a9?hp=622c613e12cef84c93c5df207a321fe13d0f2a7f>
- Log ----------------------------------------------------------------- commit 02960b52b40b494fa4f6e1be81db5f3459ab91a9 Author: David Mitchell <[email protected]> Date: Fri Aug 4 15:17:44 2017 +0100 set SVs_PADTMP flag on PL_sv_zero Where an op in scalar but not boolean context returns &PL_sv_zero as a more efficient way of doing sv_2mortal(newSViv(0)), the returned value must be mutable. For example my @a = (); my $r = \ scalar grep $_ == 1, @a; $$r += 10; By setting the SVs_PADTMP flag, this forces pp_srefgen() and similar to make a mortal copy of &PL_sv_zero. This kind of defeats the original optimisation, but the copy only kicks in under certain circumstances, whereas the newSViv(0) approach would create a new mortal every time. See RT #78288 for where FC suggested the problem and the solution. ----------------------------------------------------------------------- Summary of changes: sv.c | 3 ++- t/op/ref.t | 14 +++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/sv.c b/sv.c index 055f891016..087fc73f89 100644 --- a/sv.c +++ b/sv.c @@ -15927,7 +15927,8 @@ Perl_init_constants(pTHX) SvREFCNT(&PL_sv_zero) = SvREFCNT_IMMORTAL; SvFLAGS(&PL_sv_zero) = SVt_PVNV|SVf_READONLY|SVf_PROTECT |SVp_IOK|SVf_IOK|SVp_NOK|SVf_NOK - |SVp_POK|SVf_POK; + |SVp_POK|SVf_POK + |SVs_PADTMP; SvPV_set(&PL_sv_no, (char*)PL_No); SvCUR_set(&PL_sv_no, 0); diff --git a/t/op/ref.t b/t/op/ref.t index a0caf3868b..19163ef476 100644 --- a/t/op/ref.t +++ b/t/op/ref.t @@ -8,7 +8,7 @@ BEGIN { use strict qw(refs subs); -plan(253); +plan(254); # Test this first before we extend the stack with other operations. # This caused an asan failure due to a bad write past the end of the stack. @@ -862,6 +862,18 @@ for ("4eounthouonth") { is $r, 0, 'if (ref $obj0) else'; } +{ + # RT #78288 + # if an op returns &PL_sv_zero rather than newSViv(0), the + # value should be mutable. So ref (via the PADTMP flag) should + # make a mutable copy + + my @a = (); + my $r = \ scalar grep $_ == 1, @a; + $$r += 10; + is $$r, 10, "RT #78288 - mutable PL_sv_zero copy"; +} + # RT#130861: heap-use-after-free in pp_rv2sv, from asan fuzzing SKIP: { -- Perl5 Master Repository
