From 7ef9d42cef95562593dd30e0fab41e7e09fd0e0e Mon Sep 17 00:00:00 2001 From: Father Chrysostomos Date: Tue, 20 Dec 2011 23:06:20 -0800 Subject: Fixing crash in hint.t MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test that was added in 95cf23680e tickled another bug in the same code in Perl_hv_copy_hints_hv than the one it fixed, but not on the committer’s machine. Not only can a HE from a tied hash have a null entry, but it can also have an SV for its key. Treating it as a hek and trying to read flags from it may result in other code being told to free something it shouldn’t because the SV, when looked at as a hek, appeared to have the HVhek_FREEKEY flag. --- hv.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/hv.c b/hv.c index 7ce8048075..28ddcd0d67 100644 --- a/hv.c +++ b/hv.c @@ -1464,12 +1464,17 @@ Perl_hv_copy_hints_hv(pTHX_ HV *const ohv) hv_iterinit(ohv); while ((entry = hv_iternext_flags(ohv, 0))) { SV *const sv = newSVsv(HeVAL(entry)); - SV *heksv = newSVhek(HeKEY_hek(entry)); + SV *heksv = HeSVKEY(entry); + if (!heksv && sv) heksv = newSVhek(HeKEY_hek(entry)); if (sv) sv_magic(sv, NULL, PERL_MAGIC_hintselem, (char *)heksv, HEf_SVKEY); - SvREFCNT_dec(heksv); - (void)hv_store_flags(hv, HeKEY(entry), HeKLEN(entry), - sv, HeHASH(entry), HeKFLAGS(entry)); + if (heksv == HeSVKEY(entry)) + (void)hv_store_ent(hv, heksv, sv, 0); + else { + (void)hv_common(hv, heksv, HeKEY(entry), HeKLEN(entry), + HeKFLAGS(entry), HV_FETCH_ISSTORE|HV_FETCH_JUST_SV, sv, HeHASH(entry)); + SvREFCNT_dec(heksv); + } } HvRITER_set(ohv, riter); HvEITER_set(ohv, eiter); -- cgit v1.2.1