This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #82988] Skip hanging taint.t test on MirBSD 10
[perl5.git] / t / op / taint.t
1 #!./perl -T
2 #
3 # Taint tests by Tom Phoenix <rootbeer@teleport.com>.
4 #
5 # I don't claim to know all about tainting. If anyone sees
6 # tests that I've missed here, please add them. But this is
7 # better than having no tests at all, right?
8 #
9
10 BEGIN {
11     chdir 't' if -d 't';
12     @INC = '../lib';
13 }
14
15 use strict;
16 use Config;
17 use File::Spec::Functions;
18
19 BEGIN { require './test.pl'; }
20 plan tests => 340;
21
22 $| = 1;
23
24 use vars qw($ipcsysv); # did we manage to load IPC::SysV?
25
26 my ($old_env_path, $old_env_dcl_path, $old_env_term);
27 BEGIN {
28    $old_env_path = $ENV{'PATH'};
29    $old_env_dcl_path = $ENV{'DCL$PATH'};
30    $old_env_term = $ENV{'TERM'};
31   if ($^O eq 'VMS' && !defined($Config{d_setenv})) {
32       $ENV{PATH} = $ENV{PATH};
33       $ENV{TERM} = $ENV{TERM} ne ''? $ENV{TERM} : 'dummy';
34   }
35   if ($Config{'extensions'} =~ /\bIPC\/SysV\b/
36       && ($Config{d_shm} || $Config{d_msg})) {
37       eval { require IPC::SysV };
38       unless ($@) {
39           $ipcsysv++;
40           IPC::SysV->import(qw(IPC_PRIVATE IPC_RMID IPC_CREAT S_IRWXU IPC_NOWAIT));
41       }
42   }
43 }
44
45 my $Is_VMS      = $^O eq 'VMS';
46 my $Is_MSWin32  = $^O eq 'MSWin32';
47 my $Is_NetWare  = $^O eq 'NetWare';
48 my $Is_Dos      = $^O eq 'dos';
49 my $Is_Cygwin   = $^O eq 'cygwin';
50 my $Is_OpenBSD  = $^O eq 'openbsd';
51 my $Is_MirBSD   = $^O eq 'mirbsd';
52 my $Invoke_Perl = $Is_VMS      ? 'MCR Sys$Disk:[]Perl.exe' :
53                   $Is_MSWin32  ? '.\perl'               :
54                   $Is_NetWare  ? 'perl'                 :
55                                  './perl'               ;
56 my @MoreEnv = qw/IFS CDPATH ENV BASH_ENV/;
57
58 if ($Is_VMS) {
59     my (%old, $x);
60     for $x ('DCL$PATH', @MoreEnv) {
61         ($old{$x}) = $ENV{$x} =~ /^(.*)$/ if exists $ENV{$x};
62     }
63     # VMS note:  PATH and TERM are automatically created by the C
64     # library in VMS on reference to the their keys in %ENV.
65     # There is currently no way to determine if they did not exist
66     # before this test was run.
67     eval <<EndOfCleanup;
68         END {
69             \$ENV{PATH} = \$old_env_path;
70             warn "# Note: logical name 'PATH' may have been created\n";
71             \$ENV{'TERM'} = \$old_env_term;
72             warn "# Note: logical name 'TERM' may have been created\n";
73             \@ENV{keys %old} = values %old;
74             if (defined \$old_env_dcl_path) {
75                 \$ENV{'DCL\$PATH'} = \$old_env_dcl_path;
76             } else {
77                 delete \$ENV{'DCL\$PATH'};
78             }
79         }
80 EndOfCleanup
81 }
82
83 # Sources of taint:
84 #   The empty tainted value, for tainting strings
85 my $TAINT = substr($^X, 0, 0);
86 #   A tainted zero, useful for tainting numbers
87 my $TAINT0;
88 {
89     no warnings;
90     $TAINT0 = 0 + $TAINT;
91 }
92
93 # This taints each argument passed. All must be lvalues.
94 # Side effect: It also stringifies them. :-(
95 sub taint_these (@) {
96     for (@_) { $_ .= $TAINT }
97 }
98
99 # How to identify taint when you see it
100 sub any_tainted (@) {
101     not eval { join("",@_), kill 0; 1 };
102 }
103 sub tainted ($) {
104     any_tainted @_;
105 }
106 sub all_tainted (@) {
107     for (@_) { return 0 unless tainted $_ }
108     1;
109 }
110
111
112 sub test ($;$) {
113     my($ok, $diag) = @_;
114
115     my $curr_test = curr_test();
116
117     if ($ok) {
118         print "ok $curr_test\n";
119     } else {
120         print "not ok $curr_test\n";
121         printf "# Failed test at line %d\n", (caller)[2];
122         for (split m/^/m, $diag) {
123             print "# $_";
124         }
125         print "\n" unless
126             $diag eq ''
127             or substr($diag, -1) eq "\n";
128     }
129
130     next_test();
131
132     return $ok;
133 }
134
135 # We need an external program to call.
136 my $ECHO = ($Is_MSWin32 ? ".\\echo$$" : ($Is_NetWare ? "echo$$" : "./echo$$"));
137 END { unlink $ECHO }
138 open PROG, "> $ECHO" or die "Can't create $ECHO: $!";
139 print PROG 'print "@ARGV\n"', "\n";
140 close PROG;
141 my $echo = "$Invoke_Perl $ECHO";
142
143 my $TEST = catfile(curdir(), 'TEST');
144
145 # First, let's make sure that Perl is checking the dangerous
146 # environment variables. Maybe they aren't set yet, so we'll
147 # taint them ourselves.
148 {
149     $ENV{'DCL$PATH'} = '' if $Is_VMS;
150
151     if ($Is_MSWin32 && $Config{ccname} =~ /bcc32/ && ! -f 'cc3250mt.dll') {
152         my $bcc_dir;
153         foreach my $dir (split /$Config{path_sep}/, $ENV{PATH}) {
154             if (-f "$dir/cc3250mt.dll") {
155                 $bcc_dir = $dir and last;
156             }
157         }
158         if (defined $bcc_dir) {
159             require File::Copy;
160             File::Copy::copy("$bcc_dir/cc3250mt.dll", '.') or
161                 die "$0: failed to copy cc3250mt.dll: $!\n";
162             eval q{
163                 END { unlink "cc3250mt.dll" }
164             };
165         }
166     }
167     $ENV{PATH} = ($Is_Cygwin) ? '/usr/bin' : '';
168     delete @ENV{@MoreEnv};
169     $ENV{TERM} = 'dumb';
170
171     test eval { `$echo 1` } eq "1\n";
172
173     SKIP: {
174         skip "Environment tainting tests skipped", 4
175           if $Is_MSWin32 || $Is_NetWare || $Is_VMS || $Is_Dos;
176
177         my @vars = ('PATH', @MoreEnv);
178         while (my $v = $vars[0]) {
179             local $ENV{$v} = $TAINT;
180             last if eval { `$echo 1` };
181             last unless $@ =~ /^Insecure \$ENV{$v}/;
182             shift @vars;
183         }
184         test !@vars, "@vars";
185
186         # tainted $TERM is unsafe only if it contains metachars
187         local $ENV{TERM};
188         $ENV{TERM} = 'e=mc2';
189         test eval { `$echo 1` } eq "1\n";
190         $ENV{TERM} = 'e=mc2' . $TAINT;
191         test !eval { `$echo 1` };
192         test $@ =~ /^Insecure \$ENV{TERM}/, $@;
193     }
194
195     my $tmp;
196     if ($^O eq 'os2' || $^O eq 'amigaos' || $Is_MSWin32 || $Is_NetWare || $Is_Dos) {
197         print "# all directories are writeable\n";
198     }
199     else {
200         $tmp = (grep { defined and -d and (stat _)[2] & 2 }
201                      qw(sys$scratch /tmp /var/tmp /usr/tmp),
202                      @ENV{qw(TMP TEMP)})[0]
203             or print "# can't find world-writeable directory to test PATH\n";
204     }
205
206     SKIP: {
207         skip "all directories are writeable", 2 unless $tmp;
208
209         local $ENV{PATH} = $tmp;
210         test !eval { `$echo 1` };
211         test $@ =~ /^Insecure directory in \$ENV{PATH}/, $@;
212     }
213
214     SKIP: {
215         skip "This is not VMS", 4 unless $Is_VMS;
216
217         $ENV{'DCL$PATH'} = $TAINT;
218         test  eval { `$echo 1` } eq '';
219         test $@ =~ /^Insecure \$ENV{DCL\$PATH}/, $@;
220         SKIP: {
221             skip q[can't find world-writeable directory to test DCL$PATH], 2
222               unless $tmp;
223
224             $ENV{'DCL$PATH'} = $tmp;
225             test eval { `$echo 1` } eq '';
226             test $@ =~ /^Insecure directory in \$ENV{DCL\$PATH}/, $@;
227         }
228         $ENV{'DCL$PATH'} = '';
229     }
230 }
231
232 # Let's see that we can taint and untaint as needed.
233 {
234     my $foo = $TAINT;
235     test tainted $foo;
236
237     # That was a sanity check. If it failed, stop the insanity!
238     die "Taint checks don't seem to be enabled" unless tainted $foo;
239
240     $foo = "foo";
241     test not tainted $foo;
242
243     taint_these($foo);
244     test tainted $foo;
245
246     my @list = 1..10;
247     test not any_tainted @list;
248     taint_these @list[1,3,5,7,9];
249     test any_tainted @list;
250     test all_tainted @list[1,3,5,7,9];
251     test not any_tainted @list[0,2,4,6,8];
252
253     ($foo) = $foo =~ /(.+)/;
254     test not tainted $foo;
255
256     $foo = $1 if ('bar' . $TAINT) =~ /(.+)/;
257     test not tainted $foo;
258     test $foo eq 'bar';
259
260     {
261       use re 'taint';
262
263       ($foo) = ('bar' . $TAINT) =~ /(.+)/;
264       test tainted $foo;
265       test $foo eq 'bar';
266
267       $foo = $1 if ('bar' . $TAINT) =~ /(.+)/;
268       test tainted $foo;
269       test $foo eq 'bar';
270     }
271
272     $foo = $1 if 'bar' =~ /(.+)$TAINT/;
273     test tainted $foo;
274     test $foo eq 'bar';
275
276     my $pi = 4 * atan2(1,1) + $TAINT0;
277     test tainted $pi;
278
279     ($pi) = $pi =~ /(\d+\.\d+)/;
280     test not tainted $pi;
281     test sprintf("%.5f", $pi) eq '3.14159';
282 }
283
284 # How about command-line arguments? The problem is that we don't
285 # always get some, so we'll run another process with some.
286 SKIP: {
287     my $arg = tempfile();
288     open PROG, "> $arg" or die "Can't create $arg: $!";
289     print PROG q{
290         eval { join('', @ARGV), kill 0 };
291         exit 0 if $@ =~ /^Insecure dependency/;
292         print "# Oops: \$@ was [$@]\n";
293         exit 1;
294     };
295     close PROG;
296     print `$Invoke_Perl "-T" $arg and some suspect arguments`;
297     test !$?, "Exited with status $?";
298     unlink $arg;
299 }
300
301 # Reading from a file should be tainted
302 {
303     test open(FILE, $TEST), "Couldn't open '$TEST': $!";
304
305     my $block;
306     sysread(FILE, $block, 100);
307     my $line = <FILE>;
308     close FILE;
309     test tainted $block;
310     test tainted $line;
311 }
312
313 # Globs should be forbidden, except under VMS,
314 #   which doesn't spawn an external program.
315 SKIP: {
316     skip "globs should be forbidden", 2 if 1 or $Is_VMS;
317
318     my @globs = eval { <*> };
319     test @globs == 0 && $@ =~ /^Insecure dependency/;
320
321     @globs = eval { glob '*' };
322     test @globs == 0 && $@ =~ /^Insecure dependency/;
323 }
324
325 # Output of commands should be tainted
326 {
327     my $foo = `$echo abc`;
328     test tainted $foo;
329 }
330
331 # Certain system variables should be tainted
332 {
333     test all_tainted $^X, $0;
334 }
335
336 # Results of matching should all be untainted
337 {
338     my $foo = "abcdefghi" . $TAINT;
339     test tainted $foo;
340
341     $foo =~ /def/;
342     test not any_tainted $`, $&, $';
343
344     $foo =~ /(...)(...)(...)/;
345     test not any_tainted $1, $2, $3, $+;
346
347     my @bar = $foo =~ /(...)(...)(...)/;
348     test not any_tainted @bar;
349
350     test tainted $foo;  # $foo should still be tainted!
351     test $foo eq "abcdefghi";
352 }
353
354 # Operations which affect files can't use tainted data.
355 {
356     test !eval { chmod 0, $TAINT }, 'chmod';
357     test $@ =~ /^Insecure dependency/, $@;
358
359     # There is no feature test in $Config{} for truncate,
360     #   so we allow for the possibility that it's missing.
361     test !eval { truncate 'NoSuChFiLe', $TAINT0 }, 'truncate';
362     test $@ =~ /^(?:Insecure dependency|truncate not implemented)/, $@;
363
364     test !eval { rename '', $TAINT }, 'rename';
365     test $@ =~ /^Insecure dependency/, $@;
366
367     test !eval { unlink $TAINT }, 'unlink';
368     test $@ =~ /^Insecure dependency/, $@;
369
370     test !eval { utime $TAINT }, 'utime';
371     test $@ =~ /^Insecure dependency/, $@;
372
373     SKIP: {
374         skip "chown() is not available", 2 unless $Config{d_chown};
375
376         test !eval { chown -1, -1, $TAINT }, 'chown';
377         test $@ =~ /^Insecure dependency/, $@;
378     }
379
380     SKIP: {
381         skip "link() is not available", 2 unless $Config{d_link};
382
383         test !eval { link $TAINT, '' }, 'link';
384         test $@ =~ /^Insecure dependency/, $@;
385     }
386
387     SKIP: {
388         skip "symlink() is not available", 2 unless $Config{d_symlink};
389
390         test !eval { symlink $TAINT, '' }, 'symlink';
391         test $@ =~ /^Insecure dependency/, $@;
392     }
393 }
394
395 # Operations which affect directories can't use tainted data.
396 {
397     test !eval { mkdir "foo".$TAINT, 0755 . $TAINT0 }, 'mkdir';
398     test $@ =~ /^Insecure dependency/, $@;
399
400     test !eval { rmdir $TAINT }, 'rmdir';
401     test $@ =~ /^Insecure dependency/, $@;
402
403     test !eval { chdir "foo".$TAINT }, 'chdir';
404     test $@ =~ /^Insecure dependency/, $@;
405
406     SKIP: {
407         skip "chroot() is not available", 2 unless $Config{d_chroot};
408
409         test !eval { chroot $TAINT }, 'chroot';
410         test $@ =~ /^Insecure dependency/, $@;
411     }
412 }
413
414 # Some operations using files can't use tainted data.
415 {
416     my $foo = "imaginary library" . $TAINT;
417     test !eval { require $foo }, 'require';
418     test $@ =~ /^Insecure dependency/, $@;
419
420     my $filename = tempfile();  # NB: $filename isn't tainted!
421     $foo = $filename . $TAINT;
422     unlink $filename;   # in any case
423
424     test !eval { open FOO, $foo }, 'open for read';
425     test $@ eq '', $@;          # NB: This should be allowed
426
427     # Try first new style but allow also old style.
428     # We do not want the whole taint.t to fail
429     # just because Errno possibly failing.
430     test eval('$!{ENOENT}') ||
431         $! == 2 || # File not found
432         ($Is_Dos && $! == 22);
433
434     test !eval { open FOO, "> $foo" }, 'open for write';
435     test $@ =~ /^Insecure dependency/, $@;
436 }
437
438 # Commands to the system can't use tainted data
439 {
440     my $foo = $TAINT;
441
442     SKIP: {
443         skip "open('|') is not available", 4 if $^O eq 'amigaos';
444
445         test !eval { open FOO, "| x$foo" }, 'popen to';
446         test $@ =~ /^Insecure dependency/, $@;
447
448         test !eval { open FOO, "x$foo |" }, 'popen from';
449         test $@ =~ /^Insecure dependency/, $@;
450     }
451
452     test !eval { exec $TAINT }, 'exec';
453     test $@ =~ /^Insecure dependency/, $@;
454
455     test !eval { system $TAINT }, 'system';
456     test $@ =~ /^Insecure dependency/, $@;
457
458     $foo = "*";
459     taint_these $foo;
460
461     test !eval { `$echo 1$foo` }, 'backticks';
462     test $@ =~ /^Insecure dependency/, $@;
463
464     SKIP: {
465         # wildcard expansion doesn't invoke shell on VMS, so is safe
466         skip "This is not VMS", 2 unless $Is_VMS;
467     
468         test join('', eval { glob $foo } ) ne '', 'globbing';
469         test $@ eq '', $@;
470     }
471 }
472
473 # Operations which affect processes can't use tainted data.
474 {
475     test !eval { kill 0, $TAINT }, 'kill';
476     test $@ =~ /^Insecure dependency/, $@;
477
478     SKIP: {
479         skip "setpgrp() is not available", 2 unless $Config{d_setpgrp};
480
481         test !eval { setpgrp 0, $TAINT0 }, 'setpgrp';
482         test $@ =~ /^Insecure dependency/, $@;
483     }
484
485     SKIP: {
486         skip "setpriority() is not available", 2 unless $Config{d_setprior};
487
488         test !eval { setpriority 0, $TAINT0, $TAINT0 }, 'setpriority';
489         test $@ =~ /^Insecure dependency/, $@;
490     }
491 }
492
493 # Some miscellaneous operations can't use tainted data.
494 {
495     SKIP: {
496         skip "syscall() is not available", 2 unless $Config{d_syscall};
497
498         test !eval { syscall $TAINT }, 'syscall';
499         test $@ =~ /^Insecure dependency/, $@;
500     }
501
502     {
503         my $foo = "x" x 979;
504         taint_these $foo;
505         local *FOO;
506         my $temp = tempfile();
507         test open(FOO, "> $temp"), "Couldn't open $temp for write: $!";
508
509         test !eval { ioctl FOO, $TAINT0, $foo }, 'ioctl';
510         test $@ =~ /^Insecure dependency/, $@;
511
512         SKIP: {
513             skip "fcntl() is not available", 2 unless $Config{d_fcntl};
514
515             test !eval { fcntl FOO, $TAINT0, $foo }, 'fcntl';
516             test $@ =~ /^Insecure dependency/, $@;
517         }
518
519         close FOO;
520     }
521 }
522
523 # Some tests involving references
524 {
525     my $foo = 'abc' . $TAINT;
526     my $fooref = \$foo;
527     test not tainted $fooref;
528     test tainted $$fooref;
529     test tainted $foo;
530 }
531
532 # Some tests involving assignment
533 {
534     my $foo = $TAINT0;
535     my $bar = $foo;
536     test all_tainted $foo, $bar;
537     test tainted($foo = $bar);
538     test tainted($bar = $bar);
539     test tainted($bar += $bar);
540     test tainted($bar -= $bar);
541     test tainted($bar *= $bar);
542     test tainted($bar++);
543     test tainted($bar /= $bar);
544     test tainted($bar += 0);
545     test tainted($bar -= 2);
546     test tainted($bar *= -1);
547     test tainted($bar /= 1);
548     test tainted($bar--);
549     test $bar == 0;
550 }
551
552 # Test assignment and return of lists
553 {
554     my @foo = ("A", "tainted" . $TAINT, "B");
555     test not tainted $foo[0];
556     test     tainted $foo[1];
557     test not tainted $foo[2];
558     my @bar = @foo;
559     test not tainted $bar[0];
560     test     tainted $bar[1];
561     test not tainted $bar[2];
562     my @baz = eval { "A", "tainted" . $TAINT, "B" };
563     test not tainted $baz[0];
564     test     tainted $baz[1];
565     test not tainted $baz[2];
566     my @plugh = eval q[ "A", "tainted" . $TAINT, "B" ];
567     test not tainted $plugh[0];
568     test     tainted $plugh[1];
569     test not tainted $plugh[2];
570     my $nautilus = sub { "A", "tainted" . $TAINT, "B" };
571     test not tainted ((&$nautilus)[0]);
572     test     tainted ((&$nautilus)[1]);
573     test not tainted ((&$nautilus)[2]);
574     my @xyzzy = &$nautilus;
575     test not tainted $xyzzy[0];
576     test     tainted $xyzzy[1];
577     test not tainted $xyzzy[2];
578     my $red_october = sub { return "A", "tainted" . $TAINT, "B" };
579     test not tainted ((&$red_october)[0]);
580     test     tainted ((&$red_october)[1]);
581     test not tainted ((&$red_october)[2]);
582     my @corge = &$red_october;
583     test not tainted $corge[0];
584     test     tainted $corge[1];
585     test not tainted $corge[2];
586 }
587
588 # Test for system/library calls returning string data of dubious origin.
589 {
590     # No reliable %Config check for getpw*
591     SKIP: {
592         skip "getpwent() is not available", 1 unless 
593           eval { setpwent(); getpwent() };
594
595         setpwent();
596         my @getpwent = getpwent();
597         die "getpwent: $!\n" unless (@getpwent);
598         test (    not tainted $getpwent[0]
599                   and     tainted $getpwent[1]
600                   and not tainted $getpwent[2]
601                   and not tainted $getpwent[3]
602                   and not tainted $getpwent[4]
603                   and not tainted $getpwent[5]
604                   and     tainted $getpwent[6]          # ge?cos
605                   and not tainted $getpwent[7]
606                   and     tainted $getpwent[8]);        # shell
607         endpwent();
608     }
609
610     SKIP: {
611         # pretty hard to imagine not
612         skip "readdir() is not available", 1 unless $Config{d_readdir};
613
614         local(*D);
615         opendir(D, "op") or die "opendir: $!\n";
616         my $readdir = readdir(D);
617         test tainted $readdir;
618         closedir(D);
619     }
620
621     SKIP: {
622         skip "readlink() or symlink() is not available" unless 
623           $Config{d_readlink} && $Config{d_symlink};
624
625         my $symlink = "sl$$";
626         unlink($symlink);
627         my $sl = "/something/naughty";
628         # it has to be a real path on Mac OS
629         symlink($sl, $symlink) or die "symlink: $!\n";
630         my $readlink = readlink($symlink);
631         test tainted $readlink;
632         unlink($symlink);
633     }
634 }
635
636 # test bitwise ops (regression bug)
637 {
638     my $why = "y";
639     my $j = "x" | $why;
640     test not tainted $j;
641     $why = $TAINT."y";
642     $j = "x" | $why;
643     test     tainted $j;
644 }
645
646 # test target of substitution (regression bug)
647 {
648     my $why = $TAINT."y";
649     $why =~ s/y/z/;
650     test     tainted $why;
651
652     my $z = "[z]";
653     $why =~ s/$z/zee/;
654     test     tainted $why;
655
656     $why =~ s/e/'-'.$$/ge;
657     test     tainted $why;
658 }
659
660
661 SKIP: {
662     skip "no IPC::SysV", 2 unless $ipcsysv;
663
664     # test shmread
665     SKIP: {
666         skip "shm*() not available", 1 unless $Config{d_shm};
667
668         no strict 'subs';
669         my $sent = "foobar";
670         my $rcvd;
671         my $size = 2000;
672         my $id = shmget(IPC_PRIVATE, $size, S_IRWXU);
673
674         if (defined $id) {
675             if (shmwrite($id, $sent, 0, 60)) {
676                 if (shmread($id, $rcvd, 0, 60)) {
677                     substr($rcvd, index($rcvd, "\0")) = '';
678                 } else {
679                     warn "# shmread failed: $!\n";
680                 }
681             } else {
682                 warn "# shmwrite failed: $!\n";
683             }
684             shmctl($id, IPC_RMID, 0) or warn "# shmctl failed: $!\n";
685         } else {
686             warn "# shmget failed: $!\n";
687         }
688
689         skip "SysV shared memory operation failed", 1 unless 
690           $rcvd eq $sent;
691
692         test tainted $rcvd;
693     }
694
695
696     # test msgrcv
697     SKIP: {
698         skip "msg*() not available", 1 unless $Config{d_msg};
699
700         no strict 'subs';
701         my $id = msgget(IPC_PRIVATE, IPC_CREAT | S_IRWXU);
702
703         my $sent      = "message";
704         my $type_sent = 1234;
705         my $rcvd;
706         my $type_rcvd;
707
708         if (defined $id) {
709             if (msgsnd($id, pack("l! a*", $type_sent, $sent), IPC_NOWAIT)) {
710                 if (msgrcv($id, $rcvd, 60, 0, IPC_NOWAIT)) {
711                     ($type_rcvd, $rcvd) = unpack("l! a*", $rcvd);
712                 } else {
713                     warn "# msgrcv failed: $!\n";
714                 }
715             } else {
716                 warn "# msgsnd failed: $!\n";
717             }
718             msgctl($id, IPC_RMID, 0) or warn "# msgctl failed: $!\n";
719         } else {
720             warn "# msgget failed\n";
721         }
722
723         SKIP: {
724             skip "SysV message queue operation failed", 1
725               unless $rcvd eq $sent && $type_sent == $type_rcvd;
726
727             test tainted $rcvd;
728         }
729     }
730 }
731
732 {
733     # bug id 20001004.006
734
735     open IN, $TEST or warn "$0: cannot read $TEST: $!" ;
736     local $/;
737     my $a = <IN>;
738     my $b = <IN>;
739
740     ok tainted($a) && tainted($b) && !defined($b);
741
742     close IN;
743 }
744
745 {
746     # bug id 20001004.007
747
748     open IN, $TEST or warn "$0: cannot read $TEST: $!" ;
749     my $a = <IN>;
750
751     my $c = { a => 42,
752               b => $a };
753
754     ok !tainted($c->{a}) && tainted($c->{b});
755
756
757     my $d = { a => $a,
758               b => 42 };
759     ok tainted($d->{a}) && !tainted($d->{b});
760
761
762     my $e = { a => 42,
763               b => { c => $a, d => 42 } };
764     ok !tainted($e->{a}) &&
765        !tainted($e->{b}) &&
766         tainted($e->{b}->{c}) &&
767        !tainted($e->{b}->{d});
768
769     close IN;
770 }
771
772 {
773     # bug id 20010519.003
774
775     BEGIN {
776         use vars qw($has_fcntl);
777         eval { require Fcntl; import Fcntl; };
778         unless ($@) {
779             $has_fcntl = 1;
780         }
781     }
782
783     SKIP: {
784         skip "no Fcntl", 18 unless $has_fcntl;
785
786         my $evil = "foo" . $TAINT;
787
788         eval { sysopen(my $ro, $evil, &O_RDONLY) };
789         test $@ !~ /^Insecure dependency/, $@;
790         
791         eval { sysopen(my $wo, $evil, &O_WRONLY) };
792         test $@ =~ /^Insecure dependency/, $@;
793         
794         eval { sysopen(my $rw, $evil, &O_RDWR) };
795         test $@ =~ /^Insecure dependency/, $@;
796         
797         eval { sysopen(my $ap, $evil, &O_APPEND) };
798         test $@ =~ /^Insecure dependency/, $@;
799         
800         eval { sysopen(my $cr, $evil, &O_CREAT) };
801         test $@ =~ /^Insecure dependency/, $@;
802         
803         eval { sysopen(my $tr, $evil, &O_TRUNC) };
804         test $@ =~ /^Insecure dependency/, $@;
805         
806         eval { sysopen(my $ro, "foo", &O_RDONLY | $TAINT0) };
807         test $@ !~ /^Insecure dependency/, $@;
808         
809         eval { sysopen(my $wo, "foo", &O_WRONLY | $TAINT0) };
810         test $@ =~ /^Insecure dependency/, $@;
811
812         eval { sysopen(my $rw, "foo", &O_RDWR | $TAINT0) };
813         test $@ =~ /^Insecure dependency/, $@;
814
815         eval { sysopen(my $ap, "foo", &O_APPEND | $TAINT0) };
816         test $@ =~ /^Insecure dependency/, $@;
817         
818         eval { sysopen(my $cr, "foo", &O_CREAT | $TAINT0) };
819         test $@ =~ /^Insecure dependency/, $@;
820
821         eval { sysopen(my $tr, "foo", &O_TRUNC | $TAINT0) };
822         test $@ =~ /^Insecure dependency/, $@;
823
824         eval { sysopen(my $ro, "foo", &O_RDONLY, $TAINT0) };
825         test $@ !~ /^Insecure dependency/, $@;
826         
827         eval { sysopen(my $wo, "foo", &O_WRONLY, $TAINT0) };
828         test $@ =~ /^Insecure dependency/, $@;
829         
830         eval { sysopen(my $rw, "foo", &O_RDWR, $TAINT0) };
831         test $@ =~ /^Insecure dependency/, $@;
832         
833         eval { sysopen(my $ap, "foo", &O_APPEND, $TAINT0) };
834         test $@ =~ /^Insecure dependency/, $@;
835         
836         eval { sysopen(my $cr, "foo", &O_CREAT, $TAINT0) };
837         test $@ =~ /^Insecure dependency/, $@;
838
839         eval { sysopen(my $tr, "foo", &O_TRUNC, $TAINT0) };
840         test $@ =~ /^Insecure dependency/, $@;
841         
842         unlink("foo"); # not unlink($evil), because that would fail...
843     }
844 }
845
846 {
847     # bug 20010526.004
848
849     use warnings;
850
851     my $saw_warning = 0;
852     local $SIG{__WARN__} = sub { $saw_warning = 1 };
853
854     sub fmi {
855         my $divnum = shift()/1;
856         sprintf("%1.1f\n", $divnum);
857     }
858
859     fmi(21 . $TAINT);
860     fmi(37);
861     fmi(248);
862
863     test !$saw_warning;
864 }
865
866
867 {
868     # Bug ID 20010730.010
869
870     my $i = 0;
871
872     sub Tie::TIESCALAR {
873         my $class =  shift;
874         my $arg   =  shift;
875
876         bless \$arg => $class;
877     }
878
879     sub Tie::FETCH {
880         $i ++;
881         ${$_ [0]}
882     }
883
884  
885     package main;
886  
887     my $bar = "The Big Bright Green Pleasure Machine";
888     taint_these $bar;
889     tie my ($foo), Tie => $bar;
890
891     my $baz = $foo;
892
893     ok $i == 1;
894 }
895
896 {
897     # Check that all environment variables are tainted.
898     my @untainted;
899     while (my ($k, $v) = each %ENV) {
900         if (!tainted($v) &&
901             # These we have explicitly untainted or set earlier.
902             $k !~ /^(BASH_ENV|CDPATH|ENV|IFS|PATH|PERL_CORE|TEMP|TERM|TMP)$/) {
903             push @untainted, "# '$k' = '$v'\n";
904         }
905     }
906     test @untainted == 0, "untainted:\n @untainted";
907 }
908
909
910 ok( ${^TAINT} == 1, '$^TAINT is on' );
911
912 eval { ${^TAINT} = 0 };
913 ok( ${^TAINT},  '$^TAINT is not assignable' );
914 ok( $@ =~ /^Modification of a read-only value attempted/,
915                                 'Assigning to ${^TAINT} fails' );
916
917 {
918     # bug 20011111.105
919     
920     my $re1 = qr/x$TAINT/;
921     test tainted $re1;
922     
923     my $re2 = qr/^$re1\z/;
924     test tainted $re2;
925     
926     my $re3 = "$re2";
927     test tainted $re3;
928 }
929
930 SKIP: {
931     skip "system {} has different semantics on Win32", 1 if $Is_MSWin32;
932
933     # bug 20010221.005
934     local $ENV{PATH} .= $TAINT;
935     eval { system { "echo" } "/arg0", "arg1" };
936     test $@ =~ /^Insecure \$ENV/;
937 }
938
939 TODO: {
940     todo_skip 'tainted %ENV warning occludes tainted arguments warning', 22
941       if $Is_VMS;
942
943     # bug 20020208.005 plus some single arg exec/system extras
944     my $err = qr/^Insecure dependency/ ;
945     test !eval { exec $TAINT, $TAINT }, 'exec';
946     test $@ =~ $err, $@;
947     test !eval { exec $TAINT $TAINT }, 'exec';
948     test $@ =~ $err, $@;
949     test !eval { exec $TAINT $TAINT, $TAINT }, 'exec';
950     test $@ =~ $err, $@;
951     test !eval { exec $TAINT 'notaint' }, 'exec';
952     test $@ =~ $err, $@;
953     test !eval { exec {'notaint'} $TAINT }, 'exec';
954     test $@ =~ $err, $@;
955
956     test !eval { system $TAINT, $TAINT }, 'system';
957     test $@ =~ $err, $@;
958     test !eval { system $TAINT $TAINT }, 'system';
959     test $@ =~ $err, $@;
960     test !eval { system $TAINT $TAINT, $TAINT }, 'system';
961     test $@ =~ $err, $@;
962     test !eval { system $TAINT 'notaint' }, 'system';
963     test $@ =~ $err, $@;
964     test !eval { system {'notaint'} $TAINT }, 'system';
965     test $@ =~ $err, $@;
966
967     eval { 
968         no warnings;
969         system("lskdfj does not exist","with","args"); 
970     };
971     test !$@;
972
973     eval {
974         no warnings;
975         exec("lskdfj does not exist","with","args"); 
976     };
977     test !$@;
978
979     # If you add tests here update also the above skip block for VMS.
980 }
981
982 {
983     # [ID 20020704.001] taint propagation failure
984     use re 'taint';
985     $TAINT =~ /(.*)/;
986     test tainted(my $foo = $1);
987 }
988
989 {
990     # [perl #24291] this used to dump core
991     our %nonmagicalenv = ( PATH => "util" );
992     local *ENV = \%nonmagicalenv;
993     eval { system("lskdfj"); };
994     test $@ =~ /^%ENV is aliased to another variable while running with -T switch/;
995     local *ENV = *nonmagicalenv;
996     eval { system("lskdfj"); };
997     test $@ =~ /^%ENV is aliased to %nonmagicalenv while running with -T switch/;
998 }
999 {
1000     # [perl #24248]
1001     $TAINT =~ /(.*)/;
1002     test !tainted($1);
1003     my $notaint = $1;
1004     test !tainted($notaint);
1005
1006     my $l;
1007     $notaint =~ /($notaint)/;
1008     $l = $1;
1009     test !tainted($1);
1010     test !tainted($l);
1011     $notaint =~ /($TAINT)/;
1012     $l = $1;
1013     test tainted($1);
1014     test tainted($l);
1015
1016     $TAINT =~ /($notaint)/;
1017     $l = $1;
1018     test !tainted($1);
1019     test !tainted($l);
1020     $TAINT =~ /($TAINT)/;
1021     $l = $1;
1022     test tainted($1);
1023     test tainted($l);
1024
1025     my $r;
1026     ($r = $TAINT) =~ /($notaint)/;
1027     test !tainted($1);
1028     ($r = $TAINT) =~ /($TAINT)/;
1029     test tainted($1);
1030
1031     #  [perl #24674]
1032     # accessing $^O  shoudn't taint it as a side-effect;
1033     # assigning tainted data to it is now an error
1034
1035     test !tainted($^O);
1036     if (!$^X) { } elsif ($^O eq 'bar') { }
1037     test !tainted($^O);
1038     local $^O;  # We're going to clobber something test infrastructure depends on.
1039     eval '$^O = $^X';
1040     test $@ =~ /Insecure dependency in/;
1041 }
1042
1043 EFFECTIVELY_CONSTANTS: {
1044     my $tainted_number = 12 + $TAINT0;
1045     test tainted( $tainted_number );
1046
1047     # Even though it's always 0, it's still tainted
1048     my $tainted_product = $tainted_number * 0;
1049     test tainted( $tainted_product );
1050     test $tainted_product == 0;
1051 }
1052
1053 TERNARY_CONDITIONALS: {
1054     my $tainted_true  = $TAINT . "blah blah blah";
1055     my $tainted_false = $TAINT0;
1056     test tainted( $tainted_true );
1057     test tainted( $tainted_false );
1058
1059     my $result = $tainted_true ? "True" : "False";
1060     test $result eq "True";
1061     test !tainted( $result );
1062
1063     $result = $tainted_false ? "True" : "False";
1064     test $result eq "False";
1065     test !tainted( $result );
1066
1067     my $untainted_whatever = "The Fabulous Johnny Cash";
1068     my $tainted_whatever = "Soft Cell" . $TAINT;
1069
1070     $result = $tainted_true ? $tainted_whatever : $untainted_whatever;
1071     test $result eq "Soft Cell";
1072     test tainted( $result );
1073
1074     $result = $tainted_false ? $tainted_whatever : $untainted_whatever;
1075     test $result eq "The Fabulous Johnny Cash";
1076     test !tainted( $result );
1077 }
1078
1079 {
1080     # rt.perl.org 5900  $1 remains tainted if...
1081     # 1) The regular expression contains a scalar variable AND
1082     # 2) The regular expression appears in an elsif clause
1083
1084     my $foo = "abcdefghi" . $TAINT;
1085
1086     my $valid_chars = 'a-z';
1087     if ( $foo eq '' ) {
1088     }
1089     elsif ( $foo =~ /([$valid_chars]+)/o ) {
1090         test not tainted $1;
1091     }
1092
1093     if ( $foo eq '' ) {
1094     }
1095     elsif ( my @bar = $foo =~ /([$valid_chars]+)/o ) {
1096         test not any_tainted @bar;
1097     }
1098 }
1099
1100 # at scope exit, a restored localised value should have its old
1101 # taint status, not the taint status of the current statement
1102
1103 {
1104     our $x99 = $^X;
1105     test tainted $x99;
1106
1107     $x99 = '';
1108     test not tainted $x99;
1109
1110     my $c = do { local $x99; $^X };
1111     test not tainted $x99;
1112 }
1113 {
1114     our $x99 = $^X;
1115     test tainted $x99;
1116
1117     my $c = do { local $x99; '' };
1118     test tainted $x99;
1119 }
1120
1121 # an mg_get of a tainted value during localization shouldn't taint the
1122 # statement
1123
1124 {
1125     eval { local $0, eval '1' };
1126     test $@ eq '';
1127 }
1128
1129 # [perl #8262] //g loops infinitely on tainted data
1130
1131 {
1132     my @a;
1133     $a[0] = $^X . '-';
1134     $a[0]=~ m/(.)/g;
1135     cmp_ok pos($a[0]), '>', 0, "infinite m//g on arrays (aelemfast)";
1136
1137     my $i = 1;
1138     $a[$i] = $^X . '-';
1139     $a[$i]=~ m/(.)/g;
1140     cmp_ok pos($a[$i]), '>', 0, "infinite m//g on arrays (aelem)";
1141
1142     my %h;
1143     $h{a} = $^X . '-';
1144     $h{a}=~ m/(.)/g;
1145     cmp_ok pos($h{a}), '>', 0, "infinite m//g on hashes (helem)";
1146 }
1147
1148 SKIP:
1149 {
1150     my $got_dualvar;
1151     eval 'use Scalar::Util "dualvar"; $got_dualvar++';
1152     skip "No Scalar::Util::dualvar" unless $got_dualvar;
1153     my $a = Scalar::Util::dualvar(3, $^X);
1154     my $b = $a + 5;
1155     is ($b, 8, "Arithmetic on tainted dualvars works");
1156 }
1157
1158 # opening '|-' should not trigger $ENV{PATH} check
1159
1160 {
1161     SKIP: {
1162         skip "fork() is not available", 3 unless $Config{'d_fork'};
1163         skip "opening |- is not stable on threaded Open/MirBSD with taint", 3
1164             if $Config{useithreads} and $Is_OpenBSD || $Is_MirBSD;
1165
1166         $ENV{'PATH'} = $TAINT;
1167         local $SIG{'PIPE'} = 'IGNORE';
1168         eval {
1169             my $pid = open my $pipe, '|-';
1170             if (!defined $pid) {
1171                 die "open failed: $!";
1172             }
1173             if (!$pid) {
1174                 kill 'KILL', $$;        # child suicide
1175             }
1176             close $pipe;
1177         };
1178         test $@ !~ /Insecure \$ENV/, 'fork triggers %ENV check';
1179         test $@ eq '',               'pipe/fork/open/close failed';
1180         eval {
1181             open my $pipe, "|$Invoke_Perl -e 1";
1182             close $pipe;
1183         };
1184         test $@ =~ /Insecure \$ENV/, 'popen neglects %ENV check';
1185     }
1186 }
1187
1188 {
1189     package AUTOLOAD_TAINT;
1190     sub AUTOLOAD {
1191         our $AUTOLOAD;
1192         return if $AUTOLOAD =~ /DESTROY/;
1193         if ($AUTOLOAD =~ /untainted/) {
1194             main::ok(!main::tainted($AUTOLOAD), '$AUTOLOAD can be untainted');
1195         } else {
1196             main::ok(main::tainted($AUTOLOAD), '$AUTOLOAD can be tainted');
1197         }
1198     }
1199
1200     package main;
1201     my $o = bless [], 'AUTOLOAD_TAINT';
1202     $o->$TAINT;
1203     $o->untainted;
1204 }
1205
1206 {
1207     # tests for tainted format in s?printf
1208     eval { printf($TAINT . "# %s\n", "foo") };
1209     like($@, qr/^Insecure dependency in printf/, q/printf doesn't like tainted formats/);
1210     eval { printf("# %s\n", $TAINT . "foo") };
1211     ok(!$@, q/printf accepts other tainted args/);
1212     eval { sprintf($TAINT . "# %s\n", "foo") };
1213     like($@, qr/^Insecure dependency in sprintf/, q/sprintf doesn't like tainted formats/);
1214     eval { sprintf("# %s\n", $TAINT . "foo") };
1215     ok(!$@, q/sprintf accepts other tainted args/);
1216 }
1217
1218 {
1219     # 40708
1220     my $n  = 7e9;
1221     8e9 - $n;
1222
1223     my $val = $n;
1224     is ($val, '7000000000', 'Assignment to untainted variable');
1225     $val = $TAINT;
1226     $val = $n;
1227     is ($val, '7000000000', 'Assignment to tainted variable');
1228 }
1229
1230 {
1231     my $val = 0;
1232     my $tainted = '1' . $TAINT;
1233     eval '$val = eval $tainted;';
1234     is ($val, 0, "eval doesn't like tainted strings");
1235     like ($@, qr/^Insecure dependency in eval/);
1236
1237     # Rather nice code to get a tainted undef by from Rick Delaney
1238     open FH, "test.pl" or die $!;
1239     seek FH, 0, 2 or die $!;
1240     $tainted = <FH>;
1241
1242     eval 'eval $tainted';
1243     like ($@, qr/^Insecure dependency in eval/);
1244 }
1245
1246 foreach my $ord (78, 163, 256) {
1247     # 47195
1248     my $line = 'A1' . $TAINT . chr $ord;
1249     chop $line;
1250     is($line, 'A1');
1251     $line =~ /(A\S*)/;
1252     ok(!tainted($1), "\\S match with chr $ord");
1253 }
1254
1255 {
1256     # 59998
1257     sub cr { my $x = crypt($_[0], $_[1]); $x }
1258     sub co { my $x = ~$_[0]; $x }
1259     my ($a, $b);
1260     $a = cr('hello', 'foo' . $TAINT);
1261     $b = cr('hello', 'foo');
1262     ok(tainted($a),  "tainted crypt");
1263     ok(!tainted($b), "untainted crypt");
1264     $a = co('foo' . $TAINT);
1265     $b = co('foo');
1266     ok(tainted($a),  "tainted complement");
1267     ok(!tainted($b), "untainted complement");
1268 }
1269
1270 {
1271     my @data = qw(bonk zam zlonk qunckkk);
1272     # Clearly some sort of usenet bang-path
1273     my $string = $TAINT . join "!", @data;
1274
1275     ok(tainted($string), "tainted data");
1276
1277     my @got = split /!|,/, $string;
1278
1279     # each @got would be useful here, but I want the test for earlier perls
1280     for my $i (0 .. $#data) {
1281         ok(tainted($got[$i]), "tainted result $i");
1282         is($got[$i], $data[$i], "correct content $i");
1283     }
1284
1285     ok(tainted($string), "still tainted data");
1286
1287     my @got = split /[!,]/, $string;
1288
1289     # each @got would be useful here, but I want the test for earlier perls
1290     for my $i (0 .. $#data) {
1291         ok(tainted($got[$i]), "tainted result $i");
1292         is($got[$i], $data[$i], "correct content $i");
1293     }
1294
1295     ok(tainted($string), "still tainted data");
1296
1297     my @got = split /!/, $string;
1298
1299     # each @got would be useful here, but I want the test for earlier perls
1300     for my $i (0 .. $#data) {
1301         ok(tainted($got[$i]), "tainted result $i");
1302         is($got[$i], $data[$i], "correct content $i");
1303     }
1304 }
1305
1306 # Bug RT #52552 - broken by change at git commit id f337b08
1307 {
1308     my $x = $TAINT. q{print "Hello world\n"};
1309     my $y = pack "a*", $x;
1310     ok(tainted($y), "pack a* preserves tainting");
1311
1312     my $z = pack "A*", q{print "Hello world\n"}.$TAINT;
1313     ok(tainted($z), "pack A* preserves tainting");
1314
1315     my $zz = pack "a*a*", q{print "Hello world\n"}, $TAINT;
1316     ok(tainted($zz), "pack a*a* preserves tainting");
1317 }
1318
1319 # Bug RT #61976 tainted $! would show numeric rather than string value
1320
1321 {
1322     my $tainted_path = substr($^X,0,0) . "/no/such/file";
1323     my $err;
1324     # $! is used in a tainted expression, so gets tainted
1325     open my $fh, $tainted_path or $err= "$!";
1326     unlike($err, qr/^\d+$/, 'tainted $!');
1327 }
1328
1329 {
1330     # #6758: tainted values become untainted in tied hashes
1331     #         (also applies to other value magic such as pos)
1332
1333
1334     package P6758;
1335
1336     sub TIEHASH { bless {} }
1337     sub TIEARRAY { bless {} }
1338
1339     my $i = 0;
1340
1341     sub STORE {
1342         main::ok(main::tainted($_[1]), "tied arg1 tainted");
1343         main::ok(main::tainted($_[2]), "tied arg2 tainted");
1344         $i++;
1345     }
1346
1347     package main;
1348
1349     my ($k,$v) = qw(1111 val);
1350     taint_these($k,$v);
1351     tie my @array, 'P6758';
1352     tie my %hash , 'P6758';
1353     $array[$k] = $v;
1354     $hash{$k} = $v;
1355     ok $i == 2, "tied STORE called correct number of times";
1356 }
1357
1358 # Bug RT #45167 the return value of sprintf sometimes wasn't tainted
1359 # when the args were tainted. This only occured on the first use of
1360 # sprintf; after that, its TARG has taint magic attached, so setmagic
1361 # at the end works.  That's why there are multiple sprintf's below, rather
1362 # than just one wrapped in an inner loop. Also, any plaintext between
1363 # fprmat entires would correctly cause tainting to get set. so test with
1364 # "%s%s" rather than eg "%s %s".
1365
1366 {
1367     for my $var1 ($TAINT, "123") {
1368         for my $var2 ($TAINT0, "456") {
1369             my @s;
1370             push @s, sprintf '%s', $var1, $var2;
1371             push @s, sprintf ' %s', $var1, $var2;
1372             push @s, sprintf '%s%s', $var1, $var2;
1373             for (0..2) {
1374                 ok( !(
1375                         tainted($s[$_]) xor
1376                         (tainted($var1) || ($_==2 && tainted($var2)))
1377                     ),
1378                     "sprintf fmt$_, '$var1', '$var2'");
1379             }
1380         }
1381     }
1382 }
1383
1384
1385 # Bug RT #67962: old tainted $1 gets treated as tainted
1386 # in next untainted # match
1387
1388 {
1389     use re 'taint';
1390     "abc".$TAINT =~ /(.*)/; # make $1 tainted
1391     ok(tainted($1), '$1 should be tainted');
1392
1393     my $untainted = "abcdef";
1394     ok(!tainted($untainted), '$untainted should be untainted');
1395     $untainted =~ s/(abc)/$1/;
1396     ok(!tainted($untainted), '$untainted should still be untainted');
1397     $untainted =~ s/(abc)/x$1/;
1398     ok(!tainted($untainted), '$untainted should yet still be untainted');
1399 }
1400
1401 {
1402     # On Windows we can't spawn a fresh Perl interpreter unless at
1403     # least the Windows system directory (usually C:\Windows\System32)
1404     # is still on the PATH.  There is however no way to determine the
1405     # actual path on the current system without loading the Win32
1406     # module, so we just restore the original $ENV{PATH} here.
1407     local $ENV{PATH} = $ENV{PATH};
1408     $ENV{PATH} = $old_env_path if $Is_MSWin32;
1409
1410     fresh_perl_is(<<'end', "ok", { switches => [ '-T' ] },
1411     $TAINT = substr($^X, 0, 0);
1412     formline('@'.('<'x("2000".$TAINT)).' | @*', 'hallo', 'welt');
1413     print "ok";
1414 end
1415     "formline survives a tainted dynamic picture");
1416 }
1417
1418 {
1419     ok(!tainted($^A), "format accumulator not tainted yet");
1420     formline('@ | @*', 'hallo' . $TAINT, 'welt');
1421     ok(tainted($^A), "tainted formline argument makes a tainted accumulator");
1422     $^A = "";
1423     ok(!tainted($^A), "accumulator can be explicitly untainted");
1424     formline('@' .('<'*5) . ' | @*', 'hallo', 'welt');
1425     ok(!tainted($^A), "accumulator still untainted");
1426     $^A = "" . $TAINT;
1427     ok(tainted($^A), "accumulator can be explicitly tainted");
1428     formline('@' .('<'*5) . ' | @*', 'hallo', 'welt');
1429     ok(tainted($^A), "accumulator still tainted");
1430     $^A = "";
1431     ok(!tainted($^A), "accumulator untainted again");
1432     formline('@' .('<'*5) . ' | @*', 'hallo', 'welt');
1433     ok(!tainted($^A), "accumulator still untainted");
1434     formline('@' .('<'*(5+$TAINT0)) . ' | @*', 'hallo', 'welt');
1435     TODO: {
1436         local $::TODO = "get magic handled too late?";
1437         ok(tainted($^A), "the accumulator should be tainted already");
1438     }
1439     ok(tainted($^A), "tainted formline picture makes a tainted accumulator");
1440 }
1441
1442 {   # Bug #80610
1443     "Constant(1)" =~ / ^ ([a-z_]\w*) (?: [(] (.*) [)] )? $ /xi;
1444     my $a = $1;
1445     my $b = $2;
1446     ok(! tainted($a), "regex optimization of single char /[]/i doesn't taint");
1447     ok(! tainted($b), "regex optimization of single char /[]/i doesn't taint");
1448 }
1449
1450 {
1451     # RT 81230: tainted value during FETCH created extra ref to tied obj
1452
1453     package P81230;
1454     use warnings;
1455
1456     my %h;
1457
1458     sub TIEHASH {
1459         my $x = $^X; # tainted
1460         bless  \$x;
1461     }
1462     sub FETCH { my $x = $_[0]; $$x . "" }
1463
1464     tie %h, 'P81230';
1465
1466     my $w = "";
1467     local $SIG{__WARN__} = sub { $w .= "@_" };
1468
1469     untie %h if $h{"k"};
1470
1471     ::is($w, "", "RT 81230");
1472 }
1473
1474 {
1475     # Compiling a subroutine inside a tainted expression does not make the
1476     # constant folded values tainted.
1477     my $x = sub { "x" . "y" };
1478     my $y = $ENV{PATH} . $x->(); # Compile $x inside a tainted expression
1479     my $z = $x->();
1480     ok( ! tainted($z), "Constants folded value not tainted");
1481 }
1482
1483 # This may bomb out with the alarm signal so keep it last
1484 SKIP: {
1485     skip "No alarm()"  unless $Config{d_alarm};
1486     # Test from RT #41831]
1487     # [PATCH] Bug & fix: hang when using study + taint mode (perl 5.6.1, 5.8.x)
1488
1489     my $DATA = <<'END' . $TAINT;
1490 line1 is here
1491 line2 is here
1492 line3 is here
1493 line4 is here
1494
1495 END
1496
1497     #study $DATA;
1498
1499     ## don't set $SIG{ALRM}, since we'd never get to a user-level handler as
1500     ## perl is stuck in a regexp infinite loop!
1501
1502     alarm(10);
1503
1504     if ($DATA =~ /^line2.*line4/m) {
1505         fail("Should not be a match")
1506     } else {
1507         pass("Match on tainted multiline data should fail promptly");
1508     }
1509
1510     alarm(0);
1511 }
1512 __END__
1513 # Keep the previous test last