diff options
author | Father Chrysostomos <sprout@cpan.org> | 2011-09-21 00:59:02 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2011-09-21 01:02:31 -0700 |
commit | 705822126c5e218f2fe40097f9f1a204474e864b (patch) | |
tree | 4f51583d9c712ecea185ca7f8cb482cafddeef09 /hv.c | |
parent | be88a5c3cc8efc0dbee86240eabf0050554fc717 (diff) | |
download | perl-705822126c5e218f2fe40097f9f1a204474e864b.tar.gz |
[perl #99660] Remove elems from hashes before freeing them
Commit f50383f58 made the ‘HeVAL(entry) = &PL_sv_placeholder;’ in the
hash-element-deletion code unconditional. In doing so, it put it
after the if/else statement containing the SvREFCNT_dec. So the freed
SV was visible in the hash to destructors called by SvREFCNT_dec.
Diffstat (limited to 'hv.c')
-rw-r--r-- | hv.c | 8 |
1 files changed, 6 insertions, 2 deletions
@@ -1043,6 +1043,7 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, if (d_flags & G_DISCARD) { sv = HeVAL(entry); + HeVAL(entry) = &PL_sv_placeholder; if (sv) { /* deletion of method from stash */ if (isGV(sv) && isGV_with_GP(sv) && GvCVu(sv) @@ -1051,8 +1052,11 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, SvREFCNT_dec(sv); sv = NULL; } - } else sv = sv_2mortal(HeVAL(entry)); - HeVAL(entry) = &PL_sv_placeholder; + } + else { + sv = sv_2mortal(HeVAL(entry)); + HeVAL(entry) = &PL_sv_placeholder; + } /* * If a restricted hash, rather than really deleting the entry, put |