From 8505eec04db975056f12e93f306696ee3bf089ad Mon Sep 17 00:00:00 2001 From: Father Chrysostomos Date: Mon, 9 Jan 2012 22:18:56 -0800 Subject: Fix crash in hv_undef MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 60edcf09a was supposed to make things less buggy, but putting the ENTER/LEAVE in h_freeentries was a mistake, as both hv_undef and hv_clear still access the hv after calling h_freeentries. Why it didn’t crash for me is anyone’s guess. --- hv.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/hv.c b/hv.c index baeeae711f..f166968195 100644 --- a/hv.c +++ b/hv.c @@ -1566,6 +1566,8 @@ Perl_hv_clear(pTHX_ HV *hv) xhv = (XPVHV*)SvANY(hv); + ENTER; + SAVEFREESV(SvREFCNT_inc_simple_NN(hv)); if (SvREADONLY(hv) && HvARRAY(hv) != NULL) { /* restricted hash: convert all keys to placeholders */ STRLEN i; @@ -1603,6 +1605,7 @@ Perl_hv_clear(pTHX_ HV *hv) mro_isa_changed_in(hv); HvEITER_set(hv, NULL); } + LEAVE; } /* @@ -1684,20 +1687,12 @@ S_hfreeentries(pTHX_ HV *hv) STRLEN index = 0; XPVHV * const xhv = (XPVHV*)SvANY(hv); SV *sv; - const bool save = !!SvREFCNT(hv); PERL_ARGS_ASSERT_HFREEENTRIES; - if (save) { - ENTER; - SAVEFREESV(SvREFCNT_inc_simple_NN(hv)); - } - while ((sv = Perl_hfree_next_entry(aTHX_ hv, &index))||xhv->xhv_keys) { SvREFCNT_dec(sv); } - - if (save) LEAVE; } @@ -1790,6 +1785,7 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags) dVAR; register XPVHV* xhv; const char *name; + const bool save = !!SvREFCNT(hv); if (!hv) return; @@ -1814,6 +1810,10 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags) ); hv_name_set(hv, NULL, 0, 0); } + if (save) { + ENTER; + SAVEFREESV(SvREFCNT_inc_simple_NN(hv)); + } hfreeentries(hv); if (SvOOK(hv)) { struct xpvhv_aux * const aux = HvAUX(hv); @@ -1867,6 +1867,7 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags) if (SvRMAGICAL(hv)) mg_clear(MUTABLE_SV(hv)); + if (save) LEAVE; } /* -- cgit v1.2.1