X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp.c;h=60eaf2867ad62a9a114b0d9421e445ae5bc49ee4;hb=7fddc82f0212c2b411408f0a05ebb86f9e431bd9;hp=331f52244b0b8d5d369b1f6da735de5a198c6526;hpb=f39684dfccffa379f779d9b47d9ac013430ef359;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp.c b/pp.c index 331f522..60eaf28 100644 --- a/pp.c +++ b/pp.c @@ -1,7 +1,7 @@ /* pp.c * * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - * 2000, 2001, 2002, 2003, by Larry Wall and others + * 2000, 2001, 2002, 2003, 2004, by Larry Wall and others * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -168,6 +168,12 @@ PP(pp_rv2gv) } if (SvTYPE(sv) < SVt_RV) sv_upgrade(sv, SVt_RV); + if (SvPVX(sv)) { + (void)SvOOK_off(sv); /* backoff */ + if (SvLEN(sv)) + Safefree(SvPVX(sv)); + SvLEN(sv)=SvCUR(sv)=0; + } SvRV(sv) = (SV*)gv; SvROK_on(sv); SvSETMAGIC(sv); @@ -177,7 +183,7 @@ PP(pp_rv2gv) PL_op->op_private & HINT_STRICT_REFS) DIE(aTHX_ PL_no_usym, "a symbol"); if (ckWARN(WARN_UNINITIALIZED)) - report_uninit(); + report_uninit(sv); RETSETUNDEF; } sym = SvPV(sv,len); @@ -238,7 +244,7 @@ PP(pp_rv2sv) PL_op->op_private & HINT_STRICT_REFS) DIE(aTHX_ PL_no_usym, "a SCALAR"); if (ckWARN(WARN_UNINITIALIZED)) - report_uninit(); + report_uninit(sv); RETSETUNDEF; } sym = SvPV(sv, len); @@ -1386,12 +1392,18 @@ PP(pp_repeat) dSP; dATARGET; tryAMAGICbin(repeat,opASSIGN); { register IV count = POPi; + if (count < 0) + count = 0; if (GIMME == G_ARRAY && PL_op->op_private & OPpREPEAT_DOLIST) { dMARK; I32 items = SP - MARK; I32 max; + static const char list_extend[] = "panic: list extend"; max = items * count; + MEM_WRAP_CHECK_1(max, SV*, list_extend); + if (items > 0 && max > 0 && (max < items || max < count)) + Perl_croak(aTHX_ list_extend); MEXTEND(MARK, max); if (count > 1) { while (SP > MARK) { @@ -1444,6 +1456,7 @@ PP(pp_repeat) if (count < 1) SvCUR_set(TARG, 0); else { + MEM_WRAP_CHECK_1(count, len, "panic: string extend"); SvGROW(TARG, (count * len) + 1); repeatcpy(SvPVX(TARG) + len, SvPVX(TARG), len, count - 1); SvCUR(TARG) *= count; @@ -2372,6 +2385,7 @@ PP(pp_complement) register I32 anum; STRLEN len; + (void)SvPV_nomg(sv,len); /* force check for uninit var */ sv_setsv_nomg(TARG, sv); tmps = (U8*)SvPV_force(TARG, len); anum = len; @@ -2786,7 +2800,9 @@ PP(pp_int) else preferring IV has introduced a subtle behaviour change bug. OTOH relying on floating point to be accurate is a bug. */ - if (SvIOK(TOPs)) { + if (!SvOK(TOPs)) + SETu(0); + else if (SvIOK(TOPs)) { if (SvIsUV(TOPs)) { UV uv = TOPu; SETu(uv); @@ -2820,7 +2836,9 @@ PP(pp_abs) /* This will cache the NV value if string isn't actually integer */ IV iv = TOPi; - if (SvIOK(TOPs)) { + if (!SvOK(TOPs)) + SETu(0); + else if (SvIOK(TOPs)) { /* IVX is precise */ if (SvIsUV(TOPs)) { SETu(TOPu); /* force it to be numeric only */ @@ -3030,6 +3048,19 @@ PP(pp_substr) if (utf8_curlen) sv_pos_u2b(sv, &pos, &rem); tmps += pos; + /* we either return a PV or an LV. If the TARG hasn't been used + * before, or is of that type, reuse it; otherwise use a mortal + * instead. Note that LVs can have an extended lifetime, so also + * dont reuse if refcount > 1 (bug #20933) */ + if (SvTYPE(TARG) > SVt_NULL) { + if ( (SvTYPE(TARG) == SVt_PVLV) + ? (!lvalue || SvREFCNT(TARG) > 1) + : lvalue) + { + TARG = sv_newmortal(); + } + } + sv_setpvn(TARG, tmps, rem); #ifdef USE_LOCALE_COLLATE sv_unmagic(TARG, PERL_MAGIC_collxfrm); @@ -3066,8 +3097,6 @@ PP(pp_substr) sv_setpvn(sv,"",0); /* avoid lexical reincarnation */ } - if (SvREFCNT(TARG) > 1) /* don't share the TARG (#20933) */ - TARG = sv_newmortal(); if (SvTYPE(TARG) < SVt_PVLV) { sv_upgrade(TARG, SVt_PVLV); sv_magic(TARG, Nullsv, PERL_MAGIC_substr, Nullch, 0); @@ -3770,7 +3799,10 @@ PP(pp_delete) SP = ORIGMARK; else if (gimme == G_SCALAR) { MARK = ORIGMARK; - *++MARK = *SP; + if (SP > MARK) + *++MARK = *SP; + else + *++MARK = &PL_sv_undef; SP = MARK; } } @@ -4611,7 +4643,7 @@ PP(pp_split) if (TOPs && !make_mortal) sv_2mortal(TOPs); iters--; - SP--; + *SP-- = &PL_sv_undef; } }