summaryrefslogtreecommitdiff
path: root/hv.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2011-09-21 00:59:02 -0700
committerFather Chrysostomos <sprout@cpan.org>2011-09-21 01:02:31 -0700
commit705822126c5e218f2fe40097f9f1a204474e864b (patch)
tree4f51583d9c712ecea185ca7f8cb482cafddeef09 /hv.c
parentbe88a5c3cc8efc0dbee86240eabf0050554fc717 (diff)
downloadperl-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.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/hv.c b/hv.c
index ccd72fdfe9..6872aaac43 100644
--- a/hv.c
+++ b/hv.c
@@ -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