X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=scope.c;h=673b64cf8ba5379bf3be7de65d465007855cdea1;hb=47c8db80932508b6333745f2c283d5a98bf9cccb;hp=59adddf66f76fc410af662556fa621f98f8d81a2;hpb=05ec9bb346c404c8906ed1ac374d4bce61c84f5d;p=p5sagit%2Fp5-mst-13.2.git diff --git a/scope.c b/scope.c index 59adddf..673b64c 100644 --- a/scope.c +++ b/scope.c @@ -1,6 +1,6 @@ /* scope.c * - * Copyright (c) 1991-2001, Larry Wall + * Copyright (c) 1991-2002, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -81,14 +81,21 @@ Perl_new_stackinfo(pTHX_ I32 stitems, I32 cxitems) si->si_cxix = -1; si->si_type = PERLSI_UNDEF; New(56, si->si_cxstack, cxitems, PERL_CONTEXT); + /* Without any kind of initialising PUSHSUBST() + * in pp_subst() will read uninitialised heap. */ + Poison(si->si_cxstack, cxitems, PERL_CONTEXT); return si; } I32 Perl_cxinc(pTHX) { + IV old_max = cxstack_max; cxstack_max = GROW(cxstack_max); Renew(cxstack, cxstack_max + 1, PERL_CONTEXT); /* XXX should fix CXINC macro */ + /* Without any kind of initialising deep enough recursion + * will end up reading uninitialised PERL_CONTEXTs. */ + Poison(cxstack + old_max + 1, cxstack_max - old_max, PERL_CONTEXT); return cxstack_ix + 1; } @@ -587,23 +594,39 @@ Perl_save_destructor_x(pTHX_ DESTRUCTORFUNC_t f, void* p) void Perl_save_aelem(pTHX_ AV *av, I32 idx, SV **sptr) { + SV *sv; SSCHECK(4); SSPUSHPTR(SvREFCNT_inc(av)); SSPUSHINT(idx); SSPUSHPTR(SvREFCNT_inc(*sptr)); SSPUSHINT(SAVEt_AELEM); save_scalar_at(sptr); + sv = *sptr; + /* If we're localizing a tied array element, this new sv + * won't actually be stored in the array - so it won't get + * reaped when the localize ends. Ensure it gets reaped by + * mortifying it instead. DAPM */ + if (SvTIED_mg(sv, PERL_MAGIC_tiedelem)) + sv_2mortal(sv); } void Perl_save_helem(pTHX_ HV *hv, SV *key, SV **sptr) { + SV *sv; SSCHECK(4); SSPUSHPTR(SvREFCNT_inc(hv)); SSPUSHPTR(SvREFCNT_inc(key)); SSPUSHPTR(SvREFCNT_inc(*sptr)); SSPUSHINT(SAVEt_HELEM); save_scalar_at(sptr); + sv = *sptr; + /* If we're localizing a tied hash element, this new sv + * won't actually be stored in the hash - so it won't get + * reaped when the localize ends. Ensure it gets reaped by + * mortifying it instead. DAPM */ + if (SvTIED_mg(sv, PERL_MAGIC_tiedelem)) + sv_2mortal(sv); } void @@ -673,7 +696,11 @@ Perl_leave_scope(pTHX_ I32 base) str = (char*)SSPOPPTR; ptr = SSPOPPTR; if (*(char**)ptr != str) { +#ifdef NETWARE + PerlMem_free(*(char**)ptr); +#else PerlMemShared_free(*(char**)ptr); +#endif *(char**)ptr = str; } break; @@ -693,7 +720,9 @@ Perl_leave_scope(pTHX_ I32 base) DEBUG_S(PerlIO_printf(Perl_debug_log, "restore svref: %p %p:%s -> %p:%s\n", ptr, sv, SvPEEK(sv), value, SvPEEK(value))); - if (SvTYPE(sv) == SVt_PVMG && SvMAGIC(sv)) { + if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv) && + SvTYPE(sv) != SVt_PVGV) + { (void)SvUPGRADE(value, SvTYPE(sv)); SvMAGIC(value) = SvMAGIC(sv); SvFLAGS(value) |= SvMAGICAL(sv); @@ -705,7 +734,9 @@ Perl_leave_scope(pTHX_ I32 base) * croaking that might ensue when the SvSETMAGIC() below is * called, or to avoid two different SVs pointing at the same * SvMAGIC()). This needs a total rethink. --GSAR */ - else if (SvTYPE(value) == SVt_PVMG && SvMAGIC(value)) { + else if (SvTYPE(value) >= SVt_PVMG && SvMAGIC(value) && + SvTYPE(value) != SVt_PVGV) + { SvFLAGS(value) |= (SvFLAGS(value) & (SVp_NOK|SVp_POK)) >> PRIVSHIFT; SvMAGICAL_off(value); @@ -951,6 +982,10 @@ Perl_leave_scope(pTHX_ I32 base) PL_op = (OP*)SSPOPPTR; break; case SAVEt_HINTS: + if ((PL_hints & HINT_LOCALIZE_HH) && GvHV(PL_hintgv)) { + SvREFCNT_dec((SV*)GvHV(PL_hintgv)); + GvHV(PL_hintgv) = NULL; + } *(I32*)&PL_hints = (I32)SSPOPINT; break; case SAVEt_COMPPAD: