This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
make OP_REGCRESET only for taint handling
authorDavid Mitchell <davem@iabyn.com>
Sun, 1 Apr 2012 09:21:22 +0000 (10:21 +0100)
committerDavid Mitchell <davem@iabyn.com>
Wed, 13 Jun 2012 12:32:52 +0000 (13:32 +0100)
The OP_REGCRESET op, which is sometimes prepended to the chain of ops
leading to OP_REGCOMP, currently serves two purposes; first to reset the
taint flag, and second to initialise PL_reginterp_cnt. The second purpose
is no longer needed, and the first has a bug, in that the op isn't
prepended when "use re 'eval'" is in scope.

Fix this by prepending the op solely when PL_tainting is in effect.
This also makes run-time regexes slightly more efficient in the
non-tainting case.

dist/B-Deparse/Deparse.pm
op.c
t/op/taint.t

index 049e385..ce4bbda 100644 (file)
@@ -4587,7 +4587,10 @@ sub matchop {
        carp("found ".$kid->name." where regcomp expected");
     } else {
        ($re, $quote) = $self->regcomp($kid, 21, $extended);
-       my $matchop = $kid->first->first;
+       my $matchop = $kid->first;
+       if ($matchop->name eq 'regcrest') {
+           $matchop = $matchop->first;
+       }
        if ($matchop->name =~ /^(?:match|transr?|subst)\z/
           && $matchop->flags & OPf_SPECIAL) {
            $rhs_bound_to_defsv = 1;
diff --git a/op.c b/op.c
index c984139..304fb5d 100644 (file)
--- a/op.c
+++ b/op.c
@@ -4437,10 +4437,13 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, bool isreg, I32 floor)
            pm->op_pmflags |= PMf_CODELIST_PRIVATE;
        }
 
-       if (pm->op_pmflags & PMf_KEEP || !(PL_hints & HINT_RE_EVAL))
-           expr = newUNOP((!(PL_hints & HINT_RE_EVAL)
-                           ? OP_REGCRESET
-                           : OP_REGCMAYBE),0,expr);
+       /* the OP_REGCMAYBE is a placeholder in the non-threaded case
+        * to allow its op_next to be pointed past the regcomp and
+        * preceding stacking ops;
+        * OP_REGCRESET is there to reset taint before executing the
+        * stacking ops */
+       if (pm->op_pmflags & PMf_KEEP || PL_tainting)
+           expr = newUNOP((PL_tainting ? OP_REGCRESET : OP_REGCMAYBE),0,expr);
 
        if (pm->op_pmflags & PMf_HAS_CV) {
            /* we have a runtime qr with literal code. This means
index aec5556..c8537fc 100644 (file)
@@ -17,7 +17,7 @@ BEGIN {
 use strict;
 use Config;
 
-plan tests => 795;
+plan tests => 797;
 
 $| = 1;
 
@@ -1630,6 +1630,14 @@ TODO: {
     ($r = $TAINT) =~ /($TAINT)/;
     is_tainted($1);
 
+    {
+       use re 'eval'; # this shouldn't make any difference
+       ($r = $TAINT) =~ /($notaint)/;
+       isnt_tainted($1);
+       ($r = $TAINT) =~ /($TAINT)/;
+       is_tainted($1);
+    }
+
     #  [perl #24674]
     # accessing $^O  shoudn't taint it as a side-effect;
     # assigning tainted data to it is now an error