memNE(RX_PRECOMP(re), t, len))
{
const regexp_engine *eng = re ? RX_ENGINE(re) : NULL;
- U32 pm_flags = pm->op_pmflags & PMf_COMPILETIME;
+ U32 pm_flags = pm->op_pmflags & RXf_PMf_COMPILETIME;
if (re) {
ReREFCNT_dec(re);
#ifdef USE_ITHREADS
#ifndef INCOMPLETE_TAINTS
if (PL_tainting) {
- if (PL_tainted)
+ if (PL_tainted) {
+ SvTAINTED_on((SV*)re);
RX_EXTFLAGS(re) |= RXf_TAINTED;
- else
- RX_EXTFLAGS(re) &= ~RXf_TAINTED;
+ }
}
#endif
SvGETMAGIC(TOPs); /* possibly clear taint on $1 etc: #67962 */
- if (!(cx->sb_rxtainted & 2) && SvTAINTED(TOPs))
- cx->sb_rxtainted |= 2;
+ /* See "how taint works" above pp_subst() */
+ if (SvTAINTED(TOPs))
+ cx->sb_rxtainted |= SUBST_TAINT_REPL;
sv_catsv_nomg(dstr, POPs);
/* XXX: adjust for positive offsets of \G for instance s/(.)\G//g with positive pos() */
s -= RX_GOFS(rx);
else
sv_catpvn(dstr, s, cx->sb_strend - s);
}
- cx->sb_rxtainted |= RX_MATCH_TAINTED(rx);
+ if (RX_MATCH_TAINTED(rx)) /* run time pattern taint, eg locale */
+ cx->sb_rxtainted |= SUBST_TAINT_PAT;
#ifdef PERL_OLD_COPY_ON_WRITE
if (SvIsCOW(targ)) {
SvUTF8_on(targ);
SvPV_set(dstr, NULL);
- TAINT_IF(cx->sb_rxtainted & 1);
if (pm->op_pmflags & PMf_NONDESTRUCT)
PUSHs(targ);
else
mPUSHi(saviters - 1);
(void)SvPOK_only_UTF8(targ);
- TAINT_IF(cx->sb_rxtainted);
- SvSETMAGIC(targ);
- SvTAINT(targ);
+ /* update the taint state of various various variables in
+ * preparation for final exit.
+ * See "how taint works" above pp_subst() */
+ if (PL_tainting) {
+ if ((cx->sb_rxtainted & SUBST_TAINT_PAT) ||
+ ((cx->sb_rxtainted & (SUBST_TAINT_STR|SUBST_TAINT_RETAINT))
+ == (SUBST_TAINT_STR|SUBST_TAINT_RETAINT))
+ )
+ (RX_MATCH_TAINTED_on(rx)); /* taint $1 et al */
+
+ if (!(cx->sb_rxtainted & SUBST_TAINT_BOOLRET)
+ && (cx->sb_rxtainted & (SUBST_TAINT_STR|SUBST_TAINT_PAT))
+ )
+ SvTAINTED_on(TOPs); /* taint return value */
+ /* needed for mg_set below */
+ PL_tainted = cBOOL(cx->sb_rxtainted &
+ (SUBST_TAINT_STR|SUBST_TAINT_PAT|SUBST_TAINT_REPL));
+ SvTAINT(TARG);
+ }
+ /* PL_tainted must be correctly set for this mg_set */
+ SvSETMAGIC(TARG);
+ TAINT_NOT;
LEAVE_SCOPE(cx->sb_oldsave);
POPSUBST(cx);
RETURNOP(pm->op_next);
+ /* NOTREACHED */
}
cx->sb_iters = saviters;
}
}
if (old != rx)
(void)ReREFCNT_inc(rx);
- cx->sb_rxtainted |= RX_MATCH_TAINTED(rx);
+ /* update the taint state of various various variables in preparation
+ * for calling the code block.
+ * See "how taint works" above pp_subst() */
+ if (PL_tainting) {
+ if (RX_MATCH_TAINTED(rx)) /* run time pattern taint, eg locale */
+ cx->sb_rxtainted |= SUBST_TAINT_PAT;
+
+ if ((cx->sb_rxtainted & SUBST_TAINT_PAT) ||
+ ((cx->sb_rxtainted & (SUBST_TAINT_STR|SUBST_TAINT_RETAINT))
+ == (SUBST_TAINT_STR|SUBST_TAINT_RETAINT))
+ )
+ (RX_MATCH_TAINTED_on(rx)); /* taint $1 et al */
+
+ if (cx->sb_iters > 1 && (cx->sb_rxtainted &
+ (SUBST_TAINT_STR|SUBST_TAINT_PAT|SUBST_TAINT_REPL)))
+ SvTAINTED_on(cx->sb_targ);
+ TAINT_NOT;
+ }
rxres_save(&cx->sb_rxres, rx);
PL_curpm = pm;
RETURNOP(pm->op_pmstashstartu.op_pmreplstart);