av = (AV*)SvRV(sv);
if (SvTYPE(av) != SVt_PVAV)
DIE("Not an ARRAY reference");
- if (op->op_private & OPpLVAL_INTRO)
- av = (AV*)save_svref((SV**)sv);
if (op->op_flags & OPf_REF) {
PUSHs((SV*)av);
RETURN;
hv = (HV*)SvRV(sv);
if (SvTYPE(hv) != SVt_PVHV)
DIE("Not a HASH reference");
- if (op->op_private & OPpLVAL_INTRO)
- hv = (HV*)save_svref((SV**)sv);
if (op->op_flags & OPf_REF) {
SETs((SV*)hv);
RETURN;
}
else {
dTARGET;
- if (HvFILL(hv)) {
- sprintf(buf, "%ld/%ld", (long)HvFILL(hv), (long)HvMAX(hv)+1);
- sv_setpv(TARG, buf);
- }
+ if (HvFILL(hv))
+ sv_setpvf(TARG, "%ld/%ld",
+ (long)HvFILL(hv), (long)HvMAX(hv) + 1);
else
sv_setiv(TARG, 0);
SETTARG;
if (op->op_private & OPpASSIGN_COMMON) {
for (relem = firstrelem; relem <= lastrelem; relem++) {
/*SUPPRESS 560*/
- if (sv = *relem)
+ if (sv = *relem) {
+ TAINT_NOT; /* Each item is independent */
*relem = sv_mortalcopy(sv);
+ }
}
}
av_extend(ary, lastrelem - relem);
i = 0;
while (relem <= lastrelem) { /* gobble up all the rest */
+ SV **didstore;
sv = NEWSV(28,0);
assert(*relem);
sv_setsv(sv,*relem);
*(relem++) = sv;
- (void)av_store(ary,i++,sv);
- if (magic)
+ didstore = av_store(ary,i++,sv);
+ if (magic) {
mg_set(sv);
+ if (!didstore)
+ SvREFCNT_dec(sv);
+ }
TAINT_NOT;
}
break;
while (relem < lastrelem) { /* gobble up all the rest */
STRLEN len;
+ HE *didstore;
if (*relem)
sv = *(relem++);
else
if (*relem)
sv_setsv(tmpstr,*relem); /* value */
*(relem++) = tmpstr;
- (void)hv_store_ent(hash,sv,tmpstr,0);
- if (magic)
+ didstore = hv_store_ent(hash,sv,tmpstr,0);
+ if (magic) {
mg_set(tmpstr);
+ if (!didstore)
+ SvREFCNT_dec(tmpstr);
+ }
TAINT_NOT;
}
if (relem == lastrelem)
++BmUSEFUL(pm->op_pmshort);
ret_no:
+ if (global && !(pm->op_pmflags & PMf_CONTINUE)) {
+ if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG)) {
+ MAGIC* mg = mg_find(TARG, 'g');
+ if (mg)
+ mg->mg_len = -1;
+ }
+ }
LEAVE_SCOPE(oldsave);
if (gimme == G_ARRAY)
RETURN;
gimme = G_SCALAR;
}
+ TAINT_NOT;
if (gimme == G_VOID)
SP = newsp;
else if (gimme == G_SCALAR) {
SP = MARK;
}
else if (gimme == G_ARRAY) {
- for (mark = newsp + 1; mark <= SP; mark++)
- if (!(SvFLAGS(*mark) & (SVs_PADTMP|SVs_TEMP)))
+ /* in case LEAVE wipes old return values */
+ for (mark = newsp + 1; mark <= SP; mark++) {
+ if (!(SvFLAGS(*mark) & (SVs_PADTMP|SVs_TEMP))) {
*mark = sv_mortalcopy(*mark);
- /* in case LEAVE wipes old return values */
+ TAINT_NOT; /* Each item is independent */
+ }
+ }
}
curpm = newpm; /* Don't pop $1 et al till now */
POPBLOCK(cx,newpm);
POPSUB1(cx); /* Delay POPSUB2 until stack values are safe */
+ TAINT_NOT;
if (gimme == G_SCALAR) {
MARK = newsp + 1;
if (MARK <= SP)
}
else if (gimme == G_ARRAY) {
for (MARK = newsp + 1; MARK <= SP; MARK++) {
- if (!SvTEMP(*MARK))
+ if (!SvTEMP(*MARK)) {
*MARK = sv_mortalcopy(*MARK);
+ TAINT_NOT; /* Each item is independent */
+ }
}
}
PUTBACK;