diff options
author | Eric Brine <ikegami@adaelis.com> | 2010-07-31 01:56:43 -0700 |
---|---|---|
committer | Rafael Garcia-Suarez <rgs@consttype.org> | 2010-08-13 13:36:29 +0200 |
commit | 2154eca77956ce145743765bea9ce269e6227984 (patch) | |
tree | 2fafd0f9d101cd03da45fb5d2f288b00c4eb00b9 /doop.c | |
parent | 0607bed5b8805b56401c29fc8c6d0f3737d5353f (diff) | |
download | perl-2154eca77956ce145743765bea9ce269e6227984.tar.gz |
Fix untimely destruction introduced by lvalue ops [RT#67838] by returning a TEMP instead of using TARG. Made appropriate TODO tests live.
Diffstat (limited to 'doop.c')
-rw-r--r-- | doop.c | 38 |
1 files changed, 16 insertions, 22 deletions
@@ -1456,32 +1456,26 @@ Perl_do_kv(pTHX) RETURN; if (gimme == G_SCALAR) { - IV i; - dTARGET; - if (PL_op->op_flags & OPf_MOD || LVRET) { /* lvalue */ - if (SvTYPE(TARG) < SVt_PVLV) { - sv_upgrade(TARG, SVt_PVLV); - sv_magic(TARG, NULL, PERL_MAGIC_nkeys, NULL, 0); - } - LvTYPE(TARG) = 'k'; - if (LvTARG(TARG) != (const SV *)keys) { - SvREFCNT_dec(LvTARG(TARG)); - LvTARG(TARG) = SvREFCNT_inc_simple(keys); - } - PUSHs(TARG); - RETURN; - } - - if (! SvTIED_mg((const SV *)keys, PERL_MAGIC_tied) ) - { - i = HvKEYS(keys); + SV * const ret = sv_2mortal(newSV_type(SVt_PVLV)); /* Not TARG RT#67838 */ + sv_magic(ret, NULL, PERL_MAGIC_nkeys, NULL, 0); + LvTYPE(ret) = 'k'; + LvTARG(ret) = SvREFCNT_inc_simple(keys); + PUSHs(ret); } else { - i = 0; - while (hv_iternext(keys)) i++; + IV i; + dTARGET; + + if (! SvTIED_mg((const SV *)keys, PERL_MAGIC_tied) ) { + i = HvKEYS(keys); + } + else { + i = 0; + while (hv_iternext(keys)) i++; + } + PUSHi( i ); } - PUSHi( i ); RETURN; } |