-if ($Is_VMS) {
- for (184..203) {print "not ok $_ # TODO tainted %ENV warning occludes tainted arguments warning\n";}
-}
-else
-{
- # bug 20020208.005 plus some extras
- # single arg exec/system are tests 80-83
- use if $] lt '5.009', warnings => FATAL => 'taint';
- my $err = $] ge '5.009' ? qr/^Insecure dependency/
- : qr/^Use of tainted arguments/;
- test 184, eval { exec $TAINT, $TAINT } eq '', 'exec';
- test 185, $@ =~ $err, $@;
- test 186, eval { exec $TAINT $TAINT } eq '', 'exec';
- test 187, $@ =~ $err, $@;
- test 188, eval { exec $TAINT $TAINT, $TAINT } eq '', 'exec';
- test 189, $@ =~ $err, $@;
- test 190, eval { exec $TAINT 'notaint' } eq '', 'exec';
- test 191, $@ =~ $err, $@;
- test 192, eval { exec {'notaint'} $TAINT } eq '', 'exec';
- test 193, $@ =~ $err, $@;
-
- test 194, eval { system $TAINT, $TAINT } eq '', 'system';
- test 195, $@ =~ $err, $@;
- test 196, eval { system $TAINT $TAINT } eq '', 'system';
- test 197, $@ =~ $err, $@;
- test 198, eval { system $TAINT $TAINT, $TAINT } eq '', 'system';
- test 199, $@ =~ $err, $@;
- test 200, eval { system $TAINT 'notaint' } eq '', 'system';
- test 201, $@ =~ $err, $@;
- test 202, eval { system {'notaint'} $TAINT } eq '', 'system';
- test 203, $@ =~ $err, $@;
-
- eval { system("lskdfj does not exist","with","args"); };
- test 204, $@ eq '';
- eval { exec("lskdfj does not exist","with","args"); };
- test 205, $@ eq '';
+
+TODO: {
+ todo_skip 'tainted %ENV warning occludes tainted arguments warning', 22
+ if $Is_VMS;
+
+ # bug 20020208.005 plus some single arg exec/system extras
+ my $err = qr/^Insecure dependency/ ;
+ test !eval { exec $TAINT, $TAINT }, 'exec';
+ test $@ =~ $err, $@;
+ test !eval { exec $TAINT $TAINT }, 'exec';
+ test $@ =~ $err, $@;
+ test !eval { exec $TAINT $TAINT, $TAINT }, 'exec';
+ test $@ =~ $err, $@;
+ test !eval { exec $TAINT 'notaint' }, 'exec';
+ test $@ =~ $err, $@;
+ test !eval { exec {'notaint'} $TAINT }, 'exec';
+ test $@ =~ $err, $@;
+
+ test !eval { system $TAINT, $TAINT }, 'system';
+ test $@ =~ $err, $@;
+ test !eval { system $TAINT $TAINT }, 'system';
+ test $@ =~ $err, $@;
+ test !eval { system $TAINT $TAINT, $TAINT }, 'system';
+ test $@ =~ $err, $@;
+ test !eval { system $TAINT 'notaint' }, 'system';
+ test $@ =~ $err, $@;
+ test !eval { system {'notaint'} $TAINT }, 'system';
+ test $@ =~ $err, $@;
+
+ eval {
+ no warnings;
+ system("lskdfj does not exist","with","args");
+ };
+ test !$@;
+
+ SKIP: {
+ skip "no exec() on MacOS Classic" if $Is_MacOS;
+
+ eval {
+ no warnings;
+ exec("lskdfj does not exist","with","args");
+ };
+ test !$@;
+ }
+
+ # If you add tests here update also the above skip block for VMS.
+}
+
+{
+ # [ID 20020704.001] taint propagation failure
+ use re 'taint';
+ $TAINT =~ /(.*)/;
+ test tainted(my $foo = $1);
+}
+
+{
+ # [perl #24291] this used to dump core
+ our %nonmagicalenv = ( PATH => "util" );
+ local *ENV = \%nonmagicalenv;
+ eval { system("lskdfj"); };
+ test $@ =~ /^%ENV is aliased to another variable while running with -T switch/;
+ local *ENV = *nonmagicalenv;
+ eval { system("lskdfj"); };
+ test $@ =~ /^%ENV is aliased to %nonmagicalenv while running with -T switch/;
+}
+{
+ # [perl #24248]
+ $TAINT =~ /(.*)/;
+ test !tainted($1);
+ my $notaint = $1;
+ test !tainted($notaint);
+
+ my $l;
+ $notaint =~ /($notaint)/;
+ $l = $1;
+ test !tainted($1);
+ test !tainted($l);
+ $notaint =~ /($TAINT)/;
+ $l = $1;
+ test tainted($1);
+ test tainted($l);
+
+ $TAINT =~ /($notaint)/;
+ $l = $1;
+ test !tainted($1);
+ test !tainted($l);
+ $TAINT =~ /($TAINT)/;
+ $l = $1;
+ test tainted($1);
+ test tainted($l);
+
+ my $r;
+ ($r = $TAINT) =~ /($notaint)/;
+ test !tainted($1);
+ ($r = $TAINT) =~ /($TAINT)/;
+ test tainted($1);
+
+ # [perl #24674]
+ # accessing $^O shoudn't taint it as a side-effect;
+ # assigning tainted data to it is now an error
+
+ test !tainted($^O);
+ if (!$^X) { } elsif ($^O eq 'bar') { }
+ test !tainted($^O);
+ eval '$^O = $^X';
+ test $@ =~ /Insecure dependency in/;
+}
+
+EFFECTIVELY_CONSTANTS: {
+ my $tainted_number = 12 + $TAINT0;
+ test tainted( $tainted_number );
+
+ # Even though it's always 0, it's still tainted
+ my $tainted_product = $tainted_number * 0;
+ test tainted( $tainted_product );
+ test $tainted_product == 0;
+}
+
+TERNARY_CONDITIONALS: {
+ my $tainted_true = $TAINT . "blah blah blah";
+ my $tainted_false = $TAINT0;
+ test tainted( $tainted_true );
+ test tainted( $tainted_false );
+
+ my $result = $tainted_true ? "True" : "False";
+ test $result eq "True";
+ test !tainted( $result );
+
+ $result = $tainted_false ? "True" : "False";
+ test $result eq "False";
+ test !tainted( $result );
+
+ my $untainted_whatever = "The Fabulous Johnny Cash";
+ my $tainted_whatever = "Soft Cell" . $TAINT;
+
+ $result = $tainted_true ? $tainted_whatever : $untainted_whatever;
+ test $result eq "Soft Cell";
+ test tainted( $result );
+
+ $result = $tainted_false ? $tainted_whatever : $untainted_whatever;
+ test $result eq "The Fabulous Johnny Cash";
+ test !tainted( $result );
+}
+
+{
+ # rt.perl.org 5900 $1 remains tainted if...
+ # 1) The regular expression contains a scalar variable AND
+ # 2) The regular expression appears in an elsif clause
+
+ my $foo = "abcdefghi" . $TAINT;
+
+ my $valid_chars = 'a-z';
+ if ( $foo eq '' ) {
+ }
+ elsif ( $foo =~ /([$valid_chars]+)/o ) {
+ test not tainted $1;
+ }
+
+ if ( $foo eq '' ) {
+ }
+ elsif ( my @bar = $foo =~ /([$valid_chars]+)/o ) {
+ test not any_tainted @bar;
+ }
+}
+
+# at scope exit, a restored localised value should have its old
+# taint status, not the taint status of the current statement
+
+{
+ our $x99 = $^X;
+ test tainted $x99;
+
+ $x99 = '';
+ test not tainted $x99;
+
+ my $c = do { local $x99; $^X };
+ test not tainted $x99;
+}
+{
+ our $x99 = $^X;
+ test tainted $x99;
+
+ my $c = do { local $x99; '' };
+ test tainted $x99;
+}
+
+# an mg_get of a tainted value during localization shouldn't taint the
+# statement
+
+{
+ eval { local $0, eval '1' };
+ test $@ eq '';
+}
+
+# [perl #8262] //g loops infinitely on tainted data
+
+{
+ my @a;
+ local $::TODO = 1;
+ $a[0] = $^X;
+ my $i = 0;
+ while($a[0]=~ m/(.)/g ) {
+ last if $i++ > 10000;
+ }
+ cmp_ok $i, '<', 10000, "infinite m//g";
+}
+
+SKIP:
+{
+ my $got_dualvar;
+ eval 'use Scalar::Util "dualvar"; $got_dualvar++';
+ skip "No Scalar::Util::dualvar" unless $got_dualvar;
+ my $a = Scalar::Util::dualvar(3, $^X);
+ my $b = $a + 5;
+ is ($b, 8, "Arithmetic on tainted dualvars works");
+}
+
+# opening '|-' should not trigger $ENV{PATH} check
+
+{
+ SKIP: {
+ skip "fork() is not available", 3 unless $Config{'d_fork'};
+ skip "opening |- is not stable on threaded OpenBSD with taint", 3
+ if $Config{useithreads} && $Is_OpenBSD;
+
+ $ENV{'PATH'} = $TAINT;
+ local $SIG{'PIPE'} = 'IGNORE';
+ eval {
+ my $pid = open my $pipe, '|-';
+ if (!defined $pid) {
+ die "open failed: $!";
+ }
+ if (!$pid) {
+ kill 'KILL', $$; # child suicide
+ }
+ close $pipe;
+ };
+ test $@ !~ /Insecure \$ENV/, 'fork triggers %ENV check';
+ test $@ eq '', 'pipe/fork/open/close failed';
+ eval {
+ open my $pipe, "|$Invoke_Perl -e 1";
+ close $pipe;
+ };
+ test $@ =~ /Insecure \$ENV/, 'popen neglects %ENV check';
+ }
+}
+
+{
+ package AUTOLOAD_TAINT;
+ sub AUTOLOAD {
+ our $AUTOLOAD;
+ return if $AUTOLOAD =~ /DESTROY/;
+ if ($AUTOLOAD =~ /untainted/) {
+ main::ok(!main::tainted($AUTOLOAD), '$AUTOLOAD can be untainted');
+ } else {
+ main::ok(main::tainted($AUTOLOAD), '$AUTOLOAD can be tainted');
+ }
+ }
+
+ package main;
+ my $o = bless [], 'AUTOLOAD_TAINT';
+ $o->$TAINT;
+ $o->untainted;
+}
+
+{
+ # tests for tainted format in s?printf
+ eval { printf($TAINT . "# %s\n", "foo") };
+ like($@, qr/^Insecure dependency in printf/, q/printf doesn't like tainted formats/);
+ eval { printf("# %s\n", $TAINT . "foo") };
+ ok(!$@, q/printf accepts other tainted args/);
+ eval { sprintf($TAINT . "# %s\n", "foo") };
+ like($@, qr/^Insecure dependency in sprintf/, q/sprintf doesn't like tainted formats/);
+ eval { sprintf("# %s\n", $TAINT . "foo") };
+ ok(!$@, q/sprintf accepts other tainted args/);
+}
+
+{
+ # 40708
+ my $n = 7e9;
+ 8e9 - $n;
+
+ my $val = $n;
+ is ($val, '7000000000', 'Assignment to untainted variable');
+ $val = $TAINT;
+ $val = $n;
+ is ($val, '7000000000', 'Assignment to tainted variable');
+}
+
+{
+ my $val = 0;
+ my $tainted = '1' . $TAINT;
+ eval '$val = eval $tainted;';
+ is ($val, 0, "eval doesn't like tainted strings");
+ like ($@, qr/^Insecure dependency in eval/);
+
+ # Rather nice code to get a tainted undef by from Rick Delaney
+ open FH, "test.pl" or die $!;
+ seek FH, 0, 2 or die $!;
+ $tainted = <FH>;
+
+ eval 'eval $tainted';
+ like ($@, qr/^Insecure dependency in eval/);
+}
+
+foreach my $ord (78, 163, 256) {
+ # 47195
+ my $line = 'A1' . $TAINT . chr $ord;
+ chop $line;
+ is($line, 'A1');
+ $line =~ /(A\S*)/;
+ local $::TODO = "Bug for UTF-8 not fixed yet" if $ord > 255;
+ ok(!tainted($1), "\\S match with chr $ord");
+}
+
+# This may bomb out with the alarm signal so keep it last
+SKIP: {
+ skip "No alarm()" unless $Config{d_alarm};
+ # Test from RT #41831]
+ # [PATCH] Bug & fix: hang when using study + taint mode (perl 5.6.1, 5.8.x)
+
+ my $DATA = <<'END' . $TAINT;
+line1 is here
+line2 is here
+line3 is here
+line4 is here
+
+END
+
+ #study $DATA;
+
+ ## don't set $SIG{ALRM}, since we'd never get to a user-level handler as
+ ## perl is stuck in a regexp infinite loop!
+
+ alarm(10);
+
+ if ($DATA =~ /^line2.*line4/m) {
+ fail("Should not be a match")
+ } else {
+ pass("Match on tainted multiline data should fail promptly");
+ }
+
+ alarm(0);