duelafn has asked for the wisdom of the Perl Monks concerning the following question:

perlsec tells us the following:

The exception to the principle of "one tainted value taints the whole expression" is with the ternary conditional operator "?:". Since code with a ternary conditional $result = $tainted_value ? "Untainted" : "Also untainted"; is effectively if ( $tainted_value ) { $result = "Untainted"; } else { $result = "Also untainted"; } it doesn't make sense for $result to be tainted.

However, this does not appear to be the whole story because those two constructions are not in fact identical as the following script demonstrates

#!/usr/bin/perl -T use warnings; use strict; use Scalar::Util qw/tainted/; # Note: $t is tainted my $t = "purple" . substr($^X,0,0); my $foo = "blah"; my $bar = "foo: $foo"; my $one; $one = $t ? "the $foo" : $bar; print "1. tainted\n" if tainted($one); my $two; $two = $t ? "the foo" : $bar; print "2. tainted\n" if tainted($two); my $three; if ($t) { $three = "the $foo"; } else { $three = $bar; } print "3. tainted\n" if tainted($three); my $four; if ($t) { $four = "the foo"; } else { $four = $bar; } print "4. tainted\n" if tainted($four); print "5. tainted\n" if tainted($bar); print "6. tainted\n" if tainted("the $foo"); my $seven = ""; $seven = "the $foo" if $t; print "7. tainted\n" if tainted($seven);

The above script prints

1. tainted 7. tainted

in perl 5.8.8 and perl 5.10.0.

For one I find edge cases like this rather interesting. But I also I wonder is whether this should be filed as a bug and whether it should be filed as a perl bug or a documentation bug.

Update: Point out that $t is tainted.
Update: Add tests 5, 6, and 7.
Update: Filed bug 59916

Good Day,
    Dean

Replies are listed 'Best First'.
Re: "one tainted value taints the whole expression"
by pjf (Curate) on Oct 15, 2008 at 09:19 UTC

    Please report this as a bug using the perlbug command. The documentation and behaviour don't match, and therefore one or both needs to be fixed.

    Based upon a glance over the code, I'd say that it's Perl that needs fixing; if this behaviour of the ternary operator is documented, and it works some of the time, then it's probably perl that needs fixing, with a note in the documentation that the ?: operator may fall down with more complex expressions.

Re: "one tainted value taints the whole expression"
by Illuminatus (Curate) on Oct 14, 2008 at 22:25 UTC
    The documentation cannot be wrong, or your second case would flag as tainted as well.

      It is correct in its statements, but at best incomplete since there is more involved and one can not fully trust the ternary operator (or even statement modifiers $blop = "the $foo" if $t).

      Good Day,
          Dean

        Unless I am missing something, the logic of the text you quoted is correct. It looks like a perl bug (not a doc bug) to me.
Re: "one tainted value taints the whole expression"
by Anonymous Monk on Oct 14, 2008 at 22:09 UTC
    I think it has to do with optimization, since "the foo" is a string constant, it doesn't get flagged as tainted, where as "the $foo" and $bar do get tainted. In either case, it doesn't matter, taint does its job :)

      $foo, $bar, and "the $foo" are not tainted. Try appending the following to the script:

      print "5. tainted\n" if tainted($bar); print "6. tainted\n" if tainted("the $foo");

      Neither line prints.

      Good Day,
          Dean

        trust to do what?