In perl.git, the branch blead has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/9274aefd575ecb452e8b3e33659780c198ca43ab?hp=798bda5901ecadfc40314834ece57421e2c50146>

- Log -----------------------------------------------------------------
commit 9274aefd575ecb452e8b3e33659780c198ca43ab
Author: David Mitchell <da...@iabyn.com>
Date:   Thu Feb 17 14:50:04 2011 +0000

    taint REGEX SVs as well as refs to them
    
    Now that REGEX is actually a first-class SV type, we can taint
    the regex SV directly, as well as the RV pointing to it.
    
    This means that this now taints:
    
        $rr = qr/$tainted/;
        $r = $$r;
        /$r/;

M       pp_ctl.c
M       pp_hot.c
M       t/op/taint.t

commit 5e79dfb9cd4496df40e823bec270c4bcde98db07
Author: David Mitchell <da...@iabyn.com>
Date:   Thu Feb 17 14:17:13 2011 +0000

    pp_subst: exit earlier after failed match
    
    If the match fails, don't bother to execute some code that prepares the
    source and replacement strings for a substitution (e.g. matching
    UTF8-ness).
    
    (This is an enhancement to ff6e92e827a143094fdf3af374056b524759194b)

M       pp_hot.c

commit 0ab462a656aa799cb05352f5ff7596c9bf6893ee
Author: David Mitchell <da...@iabyn.com>
Date:   Thu Feb 17 14:13:04 2011 +0000

    tweak the new pattern taint description

M       pp_hot.c
-----------------------------------------------------------------------

Summary of changes:
 pp_ctl.c     |    4 +++-
 pp_hot.c     |   44 ++++++++++++++++++++++++--------------------
 t/op/taint.t |   14 +++++++++++++-
 3 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/pp_ctl.c b/pp_ctl.c
index 7ff109f..f5a7a48 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -240,8 +240,10 @@ PP(pp_regcomp)
 
 #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;
     }
diff --git a/pp_hot.c b/pp_hot.c
index 740cfb0..e452f07 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1235,8 +1235,10 @@ PP(pp_qr)
        (void)sv_bless(rv, stash);
     }
 
-    if (RX_EXTFLAGS(rx) & RXf_TAINTED)
+    if (RX_EXTFLAGS(rx) & RXf_TAINTED) {
         SvTAINTED_on(rv);
+        SvTAINTED_on(SvRV(rv));
+    }
     XPUSHs(rv);
     RETURN;
 }
@@ -2059,18 +2061,19 @@ PP(pp_iter)
 /*
 A description of how taint works in pattern matching and substitution.
 
-While the pattern is being assembled and them compiled, PL_tainted will
-get set if any part of the pattern is tainted, e.g. qr/.*$tainted/.
-At the end of pattern compilation, the RXf_TAINTED flag is set on the
-pattern if PL_tainted is set.
+While the pattern is being assembled/concatenated and them compiled,
+PL_tainted will get set if any component of the pattern is tainted, e.g.
+/.*$tainted/.  At the end of pattern compilation, the RXf_TAINTED flag
+is set on the pattern if PL_tainted is set.
 
-When the pattern is copied, e.g. $r = qr/..../, the SV holding the ref the
-pattern is marked as tainted. This means that subsequent usage, such as
-/x$r/, will set PL_tainted and thus RXf_TAINTED on the new pattern too.
+When the pattern is copied, e.g. $r = qr/..../, the SV holding the ref to
+the pattern is marked as tainted. This means that subsequent usage, such
+as /x$r/, will set PL_tainted, and thus RXf_TAINTED, on the new pattern too.
 
 During execution of a pattern, locale-variant ops such as ALNUML set the
 local flag RF_tainted. At the end of execution, the engine sets the
-RXf_TAINTED_SEEN on the pattern if RF_tainted got set.
+RXf_TAINTED_SEEN on the pattern if RF_tainted got set, or clears it
+otherwise.
 
 In addition, RXf_TAINTED_SEEN is used post-execution by the get magic code
 of $1 et al to indicate whether the returned value should be tainted.
@@ -2115,8 +2118,8 @@ The overall action of pp_subst is:
     * Whenever control is being returned to perl code (either by falling
        off the "end" of pp_subst/pp_substcont, or by entering a /e block),
        use the flag bits in rxtainted to make all the appropriate types of
-       destination taint visible; e.g. set RXf_TAINTED_SEEN so that $1 et
-       al will appear tainted.
+       destination taint visible; e.g. set RXf_TAINTED_SEEN so that $1
+       et al will appear tainted.
 
 pp_match is just a simpler version of the above.
 
@@ -2251,6 +2254,15 @@ PP(pp_subst)
 
     matched = CALLREGEXEC(rx, s, strend, orig, 0, TARG, NULL,
                         r_flags | REXEC_CHECKED);
+
+    if (!matched) {
+      ret_no:
+       SPAGAIN;
+       PUSHs(rpm->op_pmflags & PMf_NONDESTRUCT ? TARG : &PL_sv_no);
+       LEAVE_SCOPE(oldsave);
+       RETURN;
+    }
+
     /* known replacement string? */
     if (dstr) {
        if (SvTAINTED(dstr))
@@ -2260,7 +2272,7 @@ PP(pp_subst)
         * but only if it matched; see
         * 
http://www.nntp.perl.org/group/perl.perl5.porters/2010/04/msg158809.html
         */
-       if (matched && DO_UTF8(dstr) && ! DO_UTF8(TARG)) {
+       if (DO_UTF8(dstr) && ! DO_UTF8(TARG)) {
            char * const orig_pvx =  SvPVX(TARG);
            const STRLEN new_len = sv_utf8_upgrade_nomg(TARG);
 
@@ -2293,14 +2305,6 @@ PP(pp_subst)
        doutf8 = FALSE;
     }
     
-    if (!matched) {
-      ret_no:
-       SPAGAIN;
-       PUSHs(rpm->op_pmflags & PMf_NONDESTRUCT ? TARG : &PL_sv_no);
-       LEAVE_SCOPE(oldsave);
-       RETURN;
-    }
-
     /* can do inplace substitution? */
     if (c
 #ifdef PERL_OLD_COPY_ON_WRITE
diff --git a/t/op/taint.t b/t/op/taint.t
index dcec7aa..c2ab75d 100644
--- a/t/op/taint.t
+++ b/t/op/taint.t
@@ -17,7 +17,7 @@ use Config;
 use File::Spec::Functions;
 
 BEGIN { require './test.pl'; }
-plan tests => 684;
+plan tests => 687;
 
 $| = 1;
 
@@ -2176,6 +2176,18 @@ end
     ok( ! tainted($z), "Constants folded value not tainted");
 }
 
+{
+    # now that regexes are first class SVs, make sure that they themselves
+    # as well as references to them are tainted
+
+    my $rr = qr/(.)$TAINT/;
+    my $r = $$rr; # bare REGEX
+    my $s ="abc";
+    ok($s =~ s/$r/x/, "match bare regex");
+    ok(tainted($s), "match bare regex taint");
+    is($s, 'xbc', "match bare regex taint value");
+}
+
 # This may bomb out with the alarm signal so keep it last
 SKIP: {
     skip "No alarm()"  unless $Config{d_alarm};

--
Perl5 Master Repository

Reply via email to