This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
t/op/magic.t: Comment for an unlink test
[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     require './test.pl';
14     skip_all_if_miniperl("no dynamic loading on miniperl, no re");
15 }
16
17 use strict;
18 use Config;
19
20 plan tests => 798;
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 tainted ($) {
101     local $@;   # Don't pollute caller's value.
102     not eval { join("",@_), kill 0; 1 };
103 }
104
105 sub is_tainted {
106     my $thing = shift;
107     local $::Level = $::Level + 1;
108     ok(tainted($thing), @_);
109 }
110
111 sub isnt_tainted {
112     my $thing = shift;
113     local $::Level = $::Level + 1;
114     ok(!tainted($thing), @_);
115 }
116
117 sub violates_taint {
118     my ($code, $what, $desc) = @_;
119     $desc //= $what;
120     local $::Level = $::Level + 1;
121     is(eval { $code->(); }, undef, $desc);
122     like($@, qr/^Insecure dependency in $what while running with -T switch/);
123 }
124
125 # We need an external program to call.
126 my $ECHO = ($Is_MSWin32 ? ".\\echo$$" : ($Is_NetWare ? "echo$$" : "./echo$$"));
127 END { unlink $ECHO }
128 open my $fh, '>', $ECHO or die "Can't create $ECHO: $!";
129 print $fh 'print "@ARGV\n"', "\n";
130 close $fh;
131 my $echo = "$Invoke_Perl $ECHO";
132
133 my $TEST = 'TEST';
134
135 # First, let's make sure that Perl is checking the dangerous
136 # environment variables. Maybe they aren't set yet, so we'll
137 # taint them ourselves.
138 {
139     $ENV{'DCL$PATH'} = '' if $Is_VMS;
140
141     $ENV{PATH} = ($Is_Cygwin) ? '/usr/bin' : '';
142     delete @ENV{@MoreEnv};
143     $ENV{TERM} = 'dumb';
144
145     is(eval { `$echo 1` }, "1\n");
146
147     SKIP: {
148         skip "Environment tainting tests skipped", 4
149           if $Is_MSWin32 || $Is_NetWare || $Is_VMS || $Is_Dos;
150
151         my @vars = ('PATH', @MoreEnv);
152         while (my $v = $vars[0]) {
153             local $ENV{$v} = $TAINT;
154             last if eval { `$echo 1` };
155             last unless $@ =~ /^Insecure \$ENV\{$v}/;
156             shift @vars;
157         }
158         is("@vars", "");
159
160         # tainted $TERM is unsafe only if it contains metachars
161         local $ENV{TERM};
162         $ENV{TERM} = 'e=mc2';
163         is(eval { `$echo 1` }, "1\n");
164         $ENV{TERM} = 'e=mc2' . $TAINT;
165         is(eval { `$echo 1` }, undef);
166         like($@, qr/^Insecure \$ENV\{TERM}/);
167     }
168
169     my $tmp;
170     if ($^O eq 'os2' || $^O eq 'amigaos' || $Is_MSWin32 || $Is_NetWare || $Is_Dos) {
171         print "# all directories are writeable\n";
172     }
173     else {
174         $tmp = (grep { defined and -d and (stat _)[2] & 2 }
175                      qw(sys$scratch /tmp /var/tmp /usr/tmp),
176                      @ENV{qw(TMP TEMP)})[0]
177             or print "# can't find world-writeable directory to test PATH\n";
178     }
179
180     SKIP: {
181         skip "all directories are writeable", 2 unless $tmp;
182
183         local $ENV{PATH} = $tmp;
184         is(eval { `$echo 1` }, undef);
185         like($@, qr/^Insecure directory in \$ENV\{PATH}/);
186     }
187
188     SKIP: {
189         skip "This is not VMS", 4 unless $Is_VMS;
190
191         $ENV{'DCL$PATH'} = $TAINT;
192         is(eval { `$echo 1` }, undef);
193         like($@, qr/^Insecure \$ENV\{DCL\$PATH}/);
194         SKIP: {
195             skip q[can't find world-writeable directory to test DCL$PATH], 2
196               unless $tmp;
197
198             $ENV{'DCL$PATH'} = $tmp;
199             is(eval { `$echo 1` }, undef);
200             like($@, qr/^Insecure directory in \$ENV\{DCL\$PATH}/);
201         }
202         $ENV{'DCL$PATH'} = '';
203     }
204 }
205
206 # Let's see that we can taint and untaint as needed.
207 {
208     my $foo = $TAINT;
209     is_tainted($foo);
210
211     # That was a sanity check. If it failed, stop the insanity!
212     die "Taint checks don't seem to be enabled" unless tainted $foo;
213
214     $foo = "foo";
215     isnt_tainted($foo);
216
217     taint_these($foo);
218     is_tainted($foo);
219
220     my @list = 1..10;
221     isnt_tainted($_) foreach @list;
222     taint_these @list[1,3,5,7,9];
223     is_tainted($_) foreach @list[1,3,5,7,9];
224     isnt_tainted($_) foreach @list[0,2,4,6,8];
225
226     ($foo) = $foo =~ /(.+)/;
227     isnt_tainted($foo);
228
229     my ($desc, $s, $res, $res2, $one);
230
231     $desc = "match with string tainted";
232
233     $s = 'abcd' . $TAINT;
234     $res = $s =~ /(.+)/;
235     $one = $1;
236     is_tainted($s,     "$desc: s tainted");
237     isnt_tainted($res, "$desc: res not tainted");
238     isnt_tainted($one, "$desc: \$1 not tainted");
239     is($res, 1,        "$desc: res value");
240     is($one, 'abcd',   "$desc: \$1 value");
241
242     $desc = "match /g with string tainted";
243
244     $s = 'abcd' . $TAINT;
245     $res = $s =~ /(.)/g;
246     $one = $1;
247     is_tainted($s,     "$desc: s tainted");
248     isnt_tainted($res, "$desc: res not tainted");
249     isnt_tainted($one, "$desc: \$1 not tainted");
250     is($res, 1,        "$desc: res value");
251     is($one, 'a',      "$desc: \$1 value");
252
253     $desc = "match with string tainted, list cxt";
254
255     $s = 'abcd' . $TAINT;
256     ($res) = $s =~ /(.+)/;
257     $one = $1;
258     is_tainted($s,     "$desc: s tainted");
259     isnt_tainted($res, "$desc: res not tainted");
260     isnt_tainted($one, "$desc: \$1 not tainted");
261     is($res, 'abcd',   "$desc: res value");
262     is($one, 'abcd',   "$desc: \$1 value");
263
264     $desc = "match /g with string tainted, list cxt";
265
266     $s = 'abcd' . $TAINT;
267     ($res, $res2) = $s =~ /(.)/g;
268     $one = $1;
269     is_tainted($s,     "$desc: s tainted");
270     isnt_tainted($res, "$desc: res not tainted");
271     isnt_tainted($res2,"$desc: res2 not tainted");
272     isnt_tainted($one, "$desc: \$1 not tainted");
273     is($res, 'a',      "$desc: res value");
274     is($res2,'b',      "$desc: res2 value");
275     is($one, 'd',      "$desc: \$1 value");
276
277     $desc = "match with pattern tainted";
278
279     $s = 'abcd';
280     $res = $s =~ /$TAINT(.+)/;
281     $one = $1;
282     isnt_tainted($s,   "$desc: s not tainted");
283     isnt_tainted($res, "$desc: res not tainted");
284     is_tainted($one,   "$desc: \$1 tainted");
285     is($res, 1,        "$desc: res value");
286     is($one, 'abcd',   "$desc: \$1 value");
287
288     $desc = "match /g with pattern tainted";
289
290     $s = 'abcd';
291     $res = $s =~ /$TAINT(.)/g;
292     $one = $1;
293     isnt_tainted($s,   "$desc: s not tainted");
294     isnt_tainted($res, "$desc: res not tainted");
295     is_tainted($one,   "$desc: \$1 tainted");
296     is($res, 1,        "$desc: res value");
297     is($one, 'a',      "$desc: \$1 value");
298
299   SKIP: {
300         skip 'No locale testing without d_setlocale', 10 if(!$Config{d_setlocale});
301
302         $desc = "match with pattern tainted via locale";
303
304         $s = 'abcd';
305         {
306             BEGIN {
307                 if($Config{d_setlocale}) {
308                     require locale; import locale;
309                 }
310             }
311             $res = $s =~ /(\w+)/; $one = $1;
312         }
313         isnt_tainted($s,   "$desc: s not tainted");
314         isnt_tainted($res, "$desc: res not tainted");
315         is_tainted($one,   "$desc: \$1 tainted");
316         is($res, 1,        "$desc: res value");
317         is($one, 'abcd',   "$desc: \$1 value");
318
319         $desc = "match /g with pattern tainted via locale";
320
321         $s = 'abcd';
322         {
323             BEGIN {
324                 if($Config{d_setlocale}) {
325                     require locale; import locale;
326                 }
327             }
328             $res = $s =~ /(\w)/g; $one = $1;
329         }
330         isnt_tainted($s,   "$desc: s not tainted");
331         isnt_tainted($res, "$desc: res not tainted");
332         is_tainted($one,   "$desc: \$1 tainted");
333         is($res, 1,        "$desc: res value");
334         is($one, 'a',      "$desc: \$1 value");
335     }
336
337     $desc = "match with pattern tainted, list cxt";
338
339     $s = 'abcd';
340     ($res) = $s =~ /$TAINT(.+)/;
341     $one = $1;
342     isnt_tainted($s,   "$desc: s not tainted");
343     is_tainted($res,   "$desc: res tainted");
344     is_tainted($one,   "$desc: \$1 tainted");
345     is($res, 'abcd',   "$desc: res value");
346     is($one, 'abcd',   "$desc: \$1 value");
347
348     $desc = "match /g with pattern tainted, list cxt";
349
350     $s = 'abcd';
351     ($res, $res2) = $s =~ /$TAINT(.)/g;
352     $one = $1;
353     isnt_tainted($s,   "$desc: s not tainted");
354     is_tainted($res,   "$desc: res tainted");
355     is_tainted($one,   "$desc: \$1 tainted");
356     is($res, 'a',      "$desc: res value");
357     is($res2,'b',      "$desc: res2 value");
358     is($one, 'd',      "$desc: \$1 value");
359
360   SKIP: {
361         skip 'No locale testing without d_setlocale', 12 if(!$Config{d_setlocale});
362
363         $desc = "match with pattern tainted via locale, list cxt";
364
365         $s = 'abcd';
366         {
367             BEGIN {
368                 if($Config{d_setlocale}) {
369                     require locale; import locale;
370                 }
371             }
372             ($res) = $s =~ /(\w+)/; $one = $1;
373         }
374         isnt_tainted($s,   "$desc: s not tainted");
375         is_tainted($res,   "$desc: res tainted");
376         is_tainted($one,   "$desc: \$1 tainted");
377         is($res, 'abcd',   "$desc: res value");
378         is($one, 'abcd',   "$desc: \$1 value");
379
380         $desc = "match /g with pattern tainted via locale, list cxt";
381
382         $s = 'abcd';
383         {
384             BEGIN {
385                 if($Config{d_setlocale}) {
386                     require locale; import locale;
387                 }
388             }
389             ($res, $res2) = $s =~ /(\w)/g; $one = $1;
390         }
391         isnt_tainted($s,   "$desc: s not tainted");
392         is_tainted($res,   "$desc: res tainted");
393         is_tainted($res2,  "$desc: res2 tainted");
394         is_tainted($one,   "$desc: \$1 tainted");
395         is($res, 'a',      "$desc: res value");
396         is($res2,'b',      "$desc: res2 value");
397         is($one, 'd',      "$desc: \$1 value");
398     }
399
400     $desc = "substitution with string tainted";
401
402     $s = 'abcd' . $TAINT;
403     $res = $s =~ s/(.+)/xyz/;
404     $one = $1;
405     is_tainted($s,     "$desc: s tainted");
406     isnt_tainted($res, "$desc: res not tainted");
407     isnt_tainted($one, "$desc: \$1 not tainted");
408     is($s,   'xyz',    "$desc: s value");
409     is($res, 1,        "$desc: res value");
410     is($one, 'abcd',   "$desc: \$1 value");
411
412     $desc = "substitution /g with string tainted";
413
414     $s = 'abcd' . $TAINT;
415     $res = $s =~ s/(.)/x/g;
416     $one = $1;
417     is_tainted($s,     "$desc: s tainted");
418     is_tainted($res,   "$desc: res tainted");
419     isnt_tainted($one, "$desc: \$1 not tainted");
420     is($s,   'xxxx',   "$desc: s value");
421     is($res, 4,        "$desc: res value");
422     is($one, 'd',      "$desc: \$1 value");
423
424     $desc = "substitution /r with string tainted";
425
426     $s = 'abcd' . $TAINT;
427     $res = $s =~ s/(.+)/xyz/r;
428     $one = $1;
429     is_tainted($s,     "$desc: s tainted");
430     is_tainted($res,   "$desc: res tainted");
431     isnt_tainted($one, "$desc: \$1 not tainted");
432     is($s,   'abcd',   "$desc: s value");
433     is($res, 'xyz',    "$desc: res value");
434     is($one, 'abcd',   "$desc: \$1 value");
435
436     $desc = "substitution /e with string tainted";
437
438     $s = 'abcd' . $TAINT;
439     $one = '';
440     $res = $s =~ s{(.+)}{
441                 $one = $one . "x"; # make sure code not tainted
442                 isnt_tainted($one, "$desc: code not tainted within /e");
443                 $one = $1;
444                 isnt_tainted($one, "$desc: \$1 not tainted within /e");
445                 "xyz";
446             }e;
447     $one = $1;
448     is_tainted($s,     "$desc: s tainted");
449     isnt_tainted($res, "$desc: res not tainted");
450     isnt_tainted($one, "$desc: \$1 not tainted");
451     is($s,   'xyz',    "$desc: s value");
452     is($res, 1,        "$desc: res value");
453     is($one, 'abcd',   "$desc: \$1 value");
454
455     $desc = "substitution with pattern tainted";
456
457     $s = 'abcd';
458     $res = $s =~ s/$TAINT(.+)/xyz/;
459     $one = $1;
460     is_tainted($s,     "$desc: s tainted");
461     isnt_tainted($res, "$desc: res not tainted");
462     is_tainted($one,   "$desc: \$1 tainted");
463     is($s,  'xyz',     "$desc: s value");
464     is($res, 1,        "$desc: res value");
465     is($one, 'abcd',   "$desc: \$1 value");
466
467     $desc = "substitution /g with pattern tainted";
468
469     $s = 'abcd';
470     $res = $s =~ s/$TAINT(.)/x/g;
471     $one = $1;
472     is_tainted($s,     "$desc: s tainted");
473     is_tainted($res,   "$desc: res tainted");
474     is_tainted($one,   "$desc: \$1 tainted");
475     is($s,  'xxxx',    "$desc: s value");
476     is($res, 4,        "$desc: res value");
477     is($one, 'd',      "$desc: \$1 value");
478
479     $desc = "substitution /ge with pattern tainted";
480
481     $s = 'abc';
482     {
483         my $i = 0;
484         my $j;
485         $res = $s =~ s{(.)$TAINT}{
486                     $j = $i; # make sure code not tainted
487                     $one = $1;
488                     isnt_tainted($j, "$desc: code not tainted within /e");
489                     $i++;
490                     if ($i == 1) {
491                         isnt_tainted($s,   "$desc: s not tainted loop 1");
492                     }
493                     else {
494                         is_tainted($s,     "$desc: s tainted loop $i");
495                     }
496                     is_tainted($one,   "$desc: \$1 tainted loop $i");
497                     $i.$TAINT;
498                 }ge;
499         $one = $1;
500     }
501     is_tainted($s,     "$desc: s tainted");
502     is_tainted($res,   "$desc: res tainted");
503     is_tainted($one,   "$desc: \$1 tainted");
504     is($s,  '123',     "$desc: s value");
505     is($res, 3,        "$desc: res value");
506     is($one, 'c',      "$desc: \$1 value");
507
508     $desc = "substitution /r with pattern tainted";
509
510     $s = 'abcd';
511     $res = $s =~ s/$TAINT(.+)/xyz/r;
512     $one = $1;
513     isnt_tainted($s,   "$desc: s not tainted");
514     is_tainted($res,   "$desc: res tainted");
515     is_tainted($one,   "$desc: \$1 tainted");
516     is($s,  'abcd',    "$desc: s value");
517     is($res, 'xyz',    "$desc: res value");
518     is($one, 'abcd',   "$desc: \$1 value");
519
520   SKIP: {
521         skip 'No locale testing without d_setlocale', 18 if(!$Config{d_setlocale});
522
523         $desc = "substitution with pattern tainted via locale";
524
525         $s = 'abcd';
526         {
527             BEGIN {
528                 if($Config{d_setlocale}) {
529                     require locale; import locale;
530                 }
531             }
532             $res = $s =~ s/(\w+)/xyz/; $one = $1;
533         }
534         is_tainted($s,     "$desc: s tainted");
535         isnt_tainted($res, "$desc: res not tainted");
536         is_tainted($one,   "$desc: \$1 tainted");
537         is($s,  'xyz',     "$desc: s value");
538         is($res, 1,        "$desc: res value");
539         is($one, 'abcd',   "$desc: \$1 value");
540
541         $desc = "substitution /g with pattern tainted via locale";
542
543         $s = 'abcd';
544         {
545             BEGIN {
546                 if($Config{d_setlocale}) {
547                     require locale; import locale;
548                 }
549             }
550             $res = $s =~ s/(\w)/x/g; $one = $1;
551         }
552         is_tainted($s,     "$desc: s tainted");
553         is_tainted($res,   "$desc: res tainted");
554         is_tainted($one,   "$desc: \$1 tainted");
555         is($s,  'xxxx',    "$desc: s value");
556         is($res, 4,        "$desc: res value");
557         is($one, 'd',      "$desc: \$1 value");
558
559         $desc = "substitution /r with pattern tainted via locale";
560
561         $s = 'abcd';
562         {
563             BEGIN {
564                 if($Config{d_setlocale}) {
565                     require locale; import locale;
566                 }
567             }
568             $res = $s =~ s/(\w+)/xyz/r; $one = $1;
569         }
570         isnt_tainted($s,   "$desc: s not tainted");
571         is_tainted($res,   "$desc: res tainted");
572         is_tainted($one,   "$desc: \$1 tainted");
573         is($s,  'abcd',    "$desc: s value");
574         is($res, 'xyz',    "$desc: res value");
575         is($one, 'abcd',   "$desc: \$1 value");
576     }
577
578     $desc = "substitution with replacement tainted";
579
580     $s = 'abcd';
581     $res = $s =~ s/(.+)/xyz$TAINT/;
582     $one = $1;
583     is_tainted($s,     "$desc: s tainted");
584     isnt_tainted($res, "$desc: res not tainted");
585     isnt_tainted($one, "$desc: \$1 not tainted");
586     is($s,  'xyz',     "$desc: s value");
587     is($res, 1,        "$desc: res value");
588     is($one, 'abcd',   "$desc: \$1 value");
589
590     $desc = "substitution /g with replacement tainted";
591
592     $s = 'abcd';
593     $res = $s =~ s/(.)/x$TAINT/g;
594     $one = $1;
595     is_tainted($s,     "$desc: s tainted");
596     isnt_tainted($res, "$desc: res not tainted");
597     isnt_tainted($one, "$desc: \$1 not tainted");
598     is($s,  'xxxx',    "$desc: s value");
599     is($res, 4,        "$desc: res value");
600     is($one, 'd',      "$desc: \$1 value");
601
602     $desc = "substitution /ge with replacement tainted";
603
604     $s = 'abc';
605     {
606         my $i = 0;
607         my $j;
608         $res = $s =~ s{(.)}{
609                     $j = $i; # make sure code not tainted
610                     $one = $1;
611                     isnt_tainted($j, "$desc: code not tainted within /e");
612                     $i++;
613                     if ($i == 1) {
614                         isnt_tainted($s,   "$desc: s not tainted loop 1");
615                     }
616                     else {
617                         is_tainted($s,     "$desc: s tainted loop $i");
618                     }
619                     isnt_tainted($one, "$desc: \$1 not tainted within /e");
620                     $i.$TAINT;
621                 }ge;
622         $one = $1;
623     }
624     is_tainted($s,     "$desc: s tainted");
625     isnt_tainted($res, "$desc: res tainted");
626     isnt_tainted($one, "$desc: \$1 not tainted");
627     is($s,  '123',     "$desc: s value");
628     is($res, 3,        "$desc: res value");
629     is($one, 'c',      "$desc: \$1 value");
630
631     $desc = "substitution /r with replacement tainted";
632
633     $s = 'abcd';
634     $res = $s =~ s/(.+)/xyz$TAINT/r;
635     $one = $1;
636     isnt_tainted($s,   "$desc: s not tainted");
637     is_tainted($res,   "$desc: res tainted");
638     isnt_tainted($one, "$desc: \$1 not tainted");
639     is($s,   'abcd',   "$desc: s value");
640     is($res, 'xyz',    "$desc: res value");
641     is($one, 'abcd',   "$desc: \$1 value");
642
643     {
644         # now do them all again with "use re 'taint"
645
646         use re 'taint';
647
648         $desc = "use re 'taint': match with string tainted";
649
650         $s = 'abcd' . $TAINT;
651         $res = $s =~ /(.+)/;
652         $one = $1;
653         is_tainted($s,     "$desc: s tainted");
654         isnt_tainted($res, "$desc: res not tainted");
655         is_tainted($one,   "$desc: \$1 tainted");
656         is($res, 1,        "$desc: res value");
657         is($one, 'abcd',   "$desc: \$1 value");
658
659         $desc = "use re 'taint': match /g with string tainted";
660
661         $s = 'abcd' . $TAINT;
662         $res = $s =~ /(.)/g;
663         $one = $1;
664         is_tainted($s,     "$desc: s tainted");
665         isnt_tainted($res, "$desc: res not tainted");
666         is_tainted($one,   "$desc: \$1 tainted");
667         is($res, 1,        "$desc: res value");
668         is($one, 'a',      "$desc: \$1 value");
669
670         $desc = "use re 'taint': match with string tainted, list cxt";
671
672         $s = 'abcd' . $TAINT;
673         ($res) = $s =~ /(.+)/;
674         $one = $1;
675         is_tainted($s,     "$desc: s tainted");
676         is_tainted($res,   "$desc: res tainted");
677         is_tainted($one,   "$desc: \$1 tainted");
678         is($res, 'abcd',   "$desc: res value");
679         is($one, 'abcd',   "$desc: \$1 value");
680
681         $desc = "use re 'taint': match /g with string tainted, list cxt";
682
683         $s = 'abcd' . $TAINT;
684         ($res, $res2) = $s =~ /(.)/g;
685         $one = $1;
686         is_tainted($s,     "$desc: s tainted");
687         is_tainted($res,   "$desc: res tainted");
688         is_tainted($res2,  "$desc: res2 tainted");
689         is_tainted($one,   "$desc: \$1 not tainted");
690         is($res, 'a',      "$desc: res value");
691         is($res2,'b',      "$desc: res2 value");
692         is($one, 'd',      "$desc: \$1 value");
693
694         $desc = "use re 'taint': match with pattern tainted";
695
696         $s = 'abcd';
697         $res = $s =~ /$TAINT(.+)/;
698         $one = $1;
699         isnt_tainted($s,   "$desc: s not tainted");
700         isnt_tainted($res, "$desc: res not tainted");
701         is_tainted($one,   "$desc: \$1 tainted");
702         is($res, 1,        "$desc: res value");
703         is($one, 'abcd',   "$desc: \$1 value");
704
705         $desc = "use re 'taint': match /g with pattern tainted";
706
707         $s = 'abcd';
708         $res = $s =~ /$TAINT(.)/g;
709         $one = $1;
710         isnt_tainted($s,   "$desc: s not tainted");
711         isnt_tainted($res, "$desc: res not tainted");
712         is_tainted($one,   "$desc: \$1 tainted");
713         is($res, 1,        "$desc: res value");
714         is($one, 'a',      "$desc: \$1 value");
715
716   SKIP: {
717         skip 'No locale testing without d_setlocale', 10 if(!$Config{d_setlocale});
718
719         $desc = "use re 'taint': match with pattern tainted via locale";
720
721         $s = 'abcd';
722         {
723             BEGIN {
724                 if($Config{d_setlocale}) {
725                     require locale; import locale;
726                 }
727             }
728             $res = $s =~ /(\w+)/; $one = $1;
729         }
730         isnt_tainted($s,   "$desc: s not tainted");
731         isnt_tainted($res, "$desc: res not tainted");
732         is_tainted($one,   "$desc: \$1 tainted");
733         is($res, 1,        "$desc: res value");
734         is($one, 'abcd',   "$desc: \$1 value");
735
736         $desc = "use re 'taint': match /g with pattern tainted via locale";
737
738         $s = 'abcd';
739         {
740             BEGIN {
741                 if($Config{d_setlocale}) {
742                     require locale; import locale;
743                 }
744             }
745             $res = $s =~ /(\w)/g; $one = $1;
746         }
747         isnt_tainted($s,   "$desc: s not tainted");
748         isnt_tainted($res, "$desc: res not tainted");
749         is_tainted($one,   "$desc: \$1 tainted");
750         is($res, 1,        "$desc: res value");
751         is($one, 'a',      "$desc: \$1 value");
752     }
753
754         $desc = "use re 'taint': match with pattern tainted, list cxt";
755
756         $s = 'abcd';
757         ($res) = $s =~ /$TAINT(.+)/;
758         $one = $1;
759         isnt_tainted($s,   "$desc: s not tainted");
760         is_tainted($res,   "$desc: res tainted");
761         is_tainted($one,   "$desc: \$1 tainted");
762         is($res, 'abcd',   "$desc: res value");
763         is($one, 'abcd',   "$desc: \$1 value");
764
765         $desc = "use re 'taint': match /g with pattern tainted, list cxt";
766
767         $s = 'abcd';
768         ($res, $res2) = $s =~ /$TAINT(.)/g;
769         $one = $1;
770         isnt_tainted($s,   "$desc: s not tainted");
771         is_tainted($res,   "$desc: res tainted");
772         is_tainted($one,   "$desc: \$1 tainted");
773         is($res, 'a',      "$desc: res value");
774         is($res2,'b',      "$desc: res2 value");
775         is($one, 'd',      "$desc: \$1 value");
776
777   SKIP: {
778         skip 'No locale testing without d_setlocale', 12 if(!$Config{d_setlocale});
779
780         $desc = "use re 'taint': match with pattern tainted via locale, list cxt";
781
782         $s = 'abcd';
783         {
784             BEGIN {
785                 if($Config{d_setlocale}) {
786                     require locale; import locale;
787                 }
788             }
789             ($res) = $s =~ /(\w+)/; $one = $1;
790         }
791         isnt_tainted($s,   "$desc: s not tainted");
792         is_tainted($res,   "$desc: res tainted");
793         is_tainted($one,   "$desc: \$1 tainted");
794         is($res, 'abcd',   "$desc: res value");
795         is($one, 'abcd',   "$desc: \$1 value");
796
797         $desc = "use re 'taint': match /g with pattern tainted via locale, list cxt";
798
799         $s = 'abcd';
800         {
801             BEGIN {
802                 if($Config{d_setlocale}) {
803                     require locale; import locale;
804                 }
805             }
806             ($res, $res2) = $s =~ /(\w)/g; $one = $1;
807         }
808         isnt_tainted($s,   "$desc: s not tainted");
809         is_tainted($res,   "$desc: res tainted");
810         is_tainted($res2,  "$desc: res2 tainted");
811         is_tainted($one,   "$desc: \$1 tainted");
812         is($res, 'a',      "$desc: res value");
813         is($res2,'b',      "$desc: res2 value");
814         is($one, 'd',      "$desc: \$1 value");
815     }
816
817         $desc = "use re 'taint': substitution with string tainted";
818
819         $s = 'abcd' . $TAINT;
820         $res = $s =~ s/(.+)/xyz/;
821         $one = $1;
822         is_tainted($s,     "$desc: s tainted");
823         isnt_tainted($res, "$desc: res not tainted");
824         is_tainted($one,   "$desc: \$1 tainted");
825         is($s,   'xyz',    "$desc: s value");
826         is($res, 1,        "$desc: res value");
827         is($one, 'abcd',   "$desc: \$1 value");
828
829         $desc = "use re 'taint': substitution /g with string tainted";
830
831         $s = 'abcd' . $TAINT;
832         $res = $s =~ s/(.)/x/g;
833         $one = $1;
834         is_tainted($s,     "$desc: s tainted");
835         is_tainted($res,   "$desc: res tainted");
836         is_tainted($one,   "$desc: \$1 tainted");
837         is($s,   'xxxx',   "$desc: s value");
838         is($res, 4,        "$desc: res value");
839         is($one, 'd',      "$desc: \$1 value");
840
841         $desc = "use re 'taint': substitution /r with string tainted";
842
843         $s = 'abcd' . $TAINT;
844         $res = $s =~ s/(.+)/xyz/r;
845         $one = $1;
846         is_tainted($s,     "$desc: s tainted");
847         is_tainted($res,   "$desc: res tainted");
848         is_tainted($one,   "$desc: \$1 tainted");
849         is($s,   'abcd',   "$desc: s value");
850         is($res, 'xyz',    "$desc: res value");
851         is($one, 'abcd',   "$desc: \$1 value");
852
853         $desc = "use re 'taint': substitution /e with string tainted";
854
855         $s = 'abcd' . $TAINT;
856         $one = '';
857         $res = $s =~ s{(.+)}{
858                     $one = $one . "x"; # make sure code not tainted
859                     isnt_tainted($one, "$desc: code not tainted within /e");
860                     $one = $1;
861                     is_tainted($one, "$desc: $1 tainted within /e");
862                     "xyz";
863                 }e;
864         $one = $1;
865         is_tainted($s,     "$desc: s tainted");
866         isnt_tainted($res, "$desc: res not tainted");
867         is_tainted($one,   "$desc: \$1 tainted");
868         is($s,   'xyz',    "$desc: s value");
869         is($res, 1,        "$desc: res value");
870         is($one, 'abcd',   "$desc: \$1 value");
871
872         $desc = "use re 'taint': substitution with pattern tainted";
873
874         $s = 'abcd';
875         $res = $s =~ s/$TAINT(.+)/xyz/;
876         $one = $1;
877         is_tainted($s,     "$desc: s tainted");
878         isnt_tainted($res, "$desc: res not tainted");
879         is_tainted($one,   "$desc: \$1 tainted");
880         is($s,  'xyz',     "$desc: s value");
881         is($res, 1,        "$desc: res value");
882         is($one, 'abcd',   "$desc: \$1 value");
883
884         $desc = "use re 'taint': substitution /g with pattern tainted";
885
886         $s = 'abcd';
887         $res = $s =~ s/$TAINT(.)/x/g;
888         $one = $1;
889         is_tainted($s,     "$desc: s tainted");
890         is_tainted($res,   "$desc: res tainted");
891         is_tainted($one,   "$desc: \$1 tainted");
892         is($s,  'xxxx',    "$desc: s value");
893         is($res, 4,        "$desc: res value");
894         is($one, 'd',      "$desc: \$1 value");
895
896         $desc = "use re 'taint': substitution /ge with pattern tainted";
897
898         $s = 'abc';
899         {
900             my $i = 0;
901             my $j;
902             $res = $s =~ s{(.)$TAINT}{
903                         $j = $i; # make sure code not tainted
904                         $one = $1;
905                         isnt_tainted($j, "$desc: code not tainted within /e");
906                         $i++;
907                         if ($i == 1) {
908                             isnt_tainted($s,   "$desc: s not tainted loop 1");
909                         }
910                         else {
911                             is_tainted($s,     "$desc: s tainted loop $i");
912                         }
913                         is_tainted($one,   "$desc: \$1 tainted loop $i");
914                         $i.$TAINT;
915                     }ge;
916             $one = $1;
917         }
918         is_tainted($s,     "$desc: s tainted");
919         is_tainted($res,   "$desc: res tainted");
920         is_tainted($one,   "$desc: \$1 tainted");
921         is($s,  '123',     "$desc: s value");
922         is($res, 3,        "$desc: res value");
923         is($one, 'c',      "$desc: \$1 value");
924
925
926         $desc = "use re 'taint': substitution /r with pattern tainted";
927
928         $s = 'abcd';
929         $res = $s =~ s/$TAINT(.+)/xyz/r;
930         $one = $1;
931         isnt_tainted($s,   "$desc: s not tainted");
932         is_tainted($res,   "$desc: res tainted");
933         is_tainted($one,   "$desc: \$1 tainted");
934         is($s,  'abcd',    "$desc: s value");
935         is($res, 'xyz',    "$desc: res value");
936         is($one, 'abcd',   "$desc: \$1 value");
937
938   SKIP: {
939         skip 'No locale testing without d_setlocale', 18 if(!$Config{d_setlocale});
940
941         $desc = "use re 'taint': substitution with pattern tainted via locale";
942
943         $s = 'abcd';
944         {
945             BEGIN {
946                 if($Config{d_setlocale}) {
947                     require locale; import locale;
948                 }
949             }
950             $res = $s =~ s/(\w+)/xyz/; $one = $1;
951         }
952         is_tainted($s,     "$desc: s tainted");
953         isnt_tainted($res, "$desc: res not tainted");
954         is_tainted($one,   "$desc: \$1 tainted");
955         is($s,  'xyz',     "$desc: s value");
956         is($res, 1,        "$desc: res value");
957         is($one, 'abcd',   "$desc: \$1 value");
958
959         $desc = "use re 'taint': substitution /g with pattern tainted via locale";
960
961         $s = 'abcd';
962         {
963             BEGIN {
964                 if($Config{d_setlocale}) {
965                     require locale; import locale;
966                 }
967             }
968             $res = $s =~ s/(\w)/x/g; $one = $1;
969         }
970         is_tainted($s,     "$desc: s tainted");
971         is_tainted($res,   "$desc: res tainted");
972         is_tainted($one,   "$desc: \$1 tainted");
973         is($s,  'xxxx',    "$desc: s value");
974         is($res, 4,        "$desc: res value");
975         is($one, 'd',      "$desc: \$1 value");
976
977         $desc = "use re 'taint': substitution /r with pattern tainted via locale";
978
979         $s = 'abcd';
980         {
981             BEGIN {
982                 if($Config{d_setlocale}) {
983                     require locale; import locale;
984                 }
985             }
986             $res = $s =~ s/(\w+)/xyz/r; $one = $1;
987         }
988         isnt_tainted($s,   "$desc: s not tainted");
989         is_tainted($res,   "$desc: res tainted");
990         is_tainted($one,   "$desc: \$1 tainted");
991         is($s,  'abcd',    "$desc: s value");
992         is($res, 'xyz',    "$desc: res value");
993         is($one, 'abcd',   "$desc: \$1 value");
994     }
995
996         $desc = "use re 'taint': substitution with replacement tainted";
997
998         $s = 'abcd';
999         $res = $s =~ s/(.+)/xyz$TAINT/;
1000         $one = $1;
1001         is_tainted($s,     "$desc: s tainted");
1002         isnt_tainted($res, "$desc: res not tainted");
1003         isnt_tainted($one, "$desc: \$1 not tainted");
1004         is($s,  'xyz',     "$desc: s value");
1005         is($res, 1,        "$desc: res value");
1006         is($one, 'abcd',   "$desc: \$1 value");
1007
1008         $desc = "use re 'taint': substitution /g with replacement tainted";
1009
1010         $s = 'abcd';
1011         $res = $s =~ s/(.)/x$TAINT/g;
1012         $one = $1;
1013         is_tainted($s,     "$desc: s tainted");
1014         isnt_tainted($res, "$desc: res not tainted");
1015         isnt_tainted($one, "$desc: \$1 not tainted");
1016         is($s,  'xxxx',    "$desc: s value");
1017         is($res, 4,        "$desc: res value");
1018         is($one, 'd',      "$desc: \$1 value");
1019
1020         $desc = "use re 'taint': substitution /ge with replacement tainted";
1021
1022         $s = 'abc';
1023         {
1024             my $i = 0;
1025             my $j;
1026             $res = $s =~ s{(.)}{
1027                         $j = $i; # make sure code not tainted
1028                         $one = $1;
1029                         isnt_tainted($j, "$desc: code not tainted within /e");
1030                         $i++;
1031                         if ($i == 1) {
1032                             isnt_tainted($s,   "$desc: s not tainted loop 1");
1033                         }
1034                         else {
1035                             is_tainted($s,     "$desc: s tainted loop $i");
1036                         }
1037                             isnt_tainted($one, "$desc: \$1 not tainted");
1038                         $i.$TAINT;
1039                     }ge;
1040             $one = $1;
1041         }
1042         is_tainted($s,     "$desc: s tainted");
1043         isnt_tainted($res, "$desc: res tainted");
1044         isnt_tainted($one, "$desc: \$1 not tainted");
1045         is($s,  '123',     "$desc: s value");
1046         is($res, 3,        "$desc: res value");
1047         is($one, 'c',      "$desc: \$1 value");
1048
1049         $desc = "use re 'taint': substitution /r with replacement tainted";
1050
1051         $s = 'abcd';
1052         $res = $s =~ s/(.+)/xyz$TAINT/r;
1053         $one = $1;
1054         isnt_tainted($s,   "$desc: s not tainted");
1055         is_tainted($res,   "$desc: res tainted");
1056         isnt_tainted($one, "$desc: \$1 not tainted");
1057         is($s,   'abcd',   "$desc: s value");
1058         is($res, 'xyz',    "$desc: res value");
1059         is($one, 'abcd',   "$desc: \$1 value");
1060     }
1061
1062     $foo = $1 if 'bar' =~ /(.+)$TAINT/;
1063     is_tainted($foo);
1064     is($foo, 'bar');
1065
1066     my $pi = 4 * atan2(1,1) + $TAINT0;
1067     is_tainted($pi);
1068
1069     ($pi) = $pi =~ /(\d+\.\d+)/;
1070     isnt_tainted($pi);
1071     is(sprintf("%.5f", $pi), '3.14159');
1072 }
1073
1074 # How about command-line arguments? The problem is that we don't
1075 # always get some, so we'll run another process with some.
1076 SKIP: {
1077     my $arg = tempfile();
1078     open $fh, '>', $arg or die "Can't create $arg: $!";
1079     print $fh q{
1080         eval { join('', @ARGV), kill 0 };
1081         exit 0 if $@ =~ /^Insecure dependency/;
1082         print "# Oops: \$@ was [$@]\n";
1083         exit 1;
1084     };
1085     close $fh or die "Can't close $arg: $!";
1086     print `$Invoke_Perl "-T" $arg and some suspect arguments`;
1087     is($?, 0, "Exited with status $?");
1088     unlink $arg;
1089 }
1090
1091 # Reading from a file should be tainted
1092 {
1093     ok(open my $fh, '<', $TEST) or diag("Couldn't open '$TEST': $!");
1094
1095     my $block;
1096     sysread($fh, $block, 100);
1097     my $line = <$fh>;
1098     close $fh;
1099     is_tainted($block);
1100     is_tainted($line);
1101 }
1102
1103 # Output of commands should be tainted
1104 {
1105     my $foo = `$echo abc`;
1106     is_tainted($foo);
1107 }
1108
1109 # Certain system variables should be tainted
1110 {
1111     is_tainted($^X);
1112     is_tainted($0);
1113 }
1114
1115 # Results of matching should all be untainted
1116 {
1117     my $foo = "abcdefghi" . $TAINT;
1118     is_tainted($foo);
1119
1120     $foo =~ /def/;
1121     isnt_tainted($`);
1122     isnt_tainted($&);
1123     isnt_tainted($');
1124
1125     $foo =~ /(...)(...)(...)/;
1126     isnt_tainted($1);
1127     isnt_tainted($2);
1128     isnt_tainted($3);
1129     isnt_tainted($+);
1130
1131     my @bar = $foo =~ /(...)(...)(...)/;
1132     isnt_tainted($_) foreach @bar;
1133
1134     is_tainted($foo);   # $foo should still be tainted!
1135     is($foo, "abcdefghi");
1136 }
1137
1138 # Operations which affect files can't use tainted data.
1139 {
1140     violates_taint(sub { chmod 0, $TAINT }, 'chmod');
1141
1142     SKIP: {
1143         skip "truncate() is not available", 2 unless $Config{d_truncate};
1144
1145         violates_taint(sub { truncate 'NoSuChFiLe', $TAINT0 }, 'truncate');
1146     }
1147
1148     violates_taint(sub { rename '', $TAINT }, 'rename');
1149     violates_taint(sub { unlink $TAINT }, 'unlink');
1150     violates_taint(sub { utime $TAINT }, 'utime');
1151
1152     SKIP: {
1153         skip "chown() is not available", 2 unless $Config{d_chown};
1154
1155         violates_taint(sub { chown -1, -1, $TAINT }, 'chown');
1156     }
1157
1158     SKIP: {
1159         skip "link() is not available", 2 unless $Config{d_link};
1160
1161 violates_taint(sub { link $TAINT, '' }, 'link');
1162     }
1163
1164     SKIP: {
1165         skip "symlink() is not available", 2 unless $Config{d_symlink};
1166
1167         violates_taint(sub { symlink $TAINT, '' }, 'symlink');
1168     }
1169 }
1170
1171 # Operations which affect directories can't use tainted data.
1172 {
1173     violates_taint(sub { mkdir "foo".$TAINT, 0755 . $TAINT0 }, 'mkdir');
1174     violates_taint(sub { rmdir $TAINT }, 'rmdir');
1175     violates_taint(sub { chdir "foo".$TAINT }, 'chdir');
1176
1177     SKIP: {
1178         skip "chroot() is not available", 2 unless $Config{d_chroot};
1179
1180         violates_taint(sub { chroot $TAINT }, 'chroot');
1181     }
1182 }
1183
1184 # Some operations using files can't use tainted data.
1185 {
1186     my $foo = "imaginary library" . $TAINT;
1187     violates_taint(sub { require $foo }, 'require');
1188
1189     my $filename = tempfile();  # NB: $filename isn't tainted!
1190     $foo = $filename . $TAINT;
1191     unlink $filename;   # in any case
1192
1193     is(eval { open FOO, $foo }, undef, 'open for read');
1194     is($@, '');                # NB: This should be allowed
1195     is(eval { open my $fh, , '<', $foo }, undef, 'open for read');
1196     is($@, '');                # NB: This should be allowed
1197
1198     # Try first new style but allow also old style.
1199     # We do not want the whole taint.t to fail
1200     # just because Errno possibly failing.
1201     ok(eval('$!{ENOENT}') ||
1202         $! == 2 || # File not found
1203         ($Is_Dos && $! == 22));
1204
1205     violates_taint(sub { open FOO, "> $foo" }, 'open', 'open for write');
1206     violates_taint(sub { open my $fh, '>', $foo }, 'open', 'open for write');
1207 }
1208
1209 # Commands to the system can't use tainted data
1210 {
1211     my $foo = $TAINT;
1212
1213     SKIP: {
1214         skip "open('|') is not available", 8 if $^O eq 'amigaos';
1215
1216         violates_taint(sub { open FOO, "| x$foo" }, 'piped open', 'popen to');
1217         violates_taint(sub { open FOO, "x$foo |" }, 'piped open', 'popen from');
1218         violates_taint(sub { open my $fh, '|-', "x$foo" }, 'piped open', 'popen to');
1219         violates_taint(sub { open my $fh, '-|', "x$foo" }, 'piped open', 'popen from');
1220     }
1221
1222     violates_taint(sub { exec $TAINT }, 'exec');
1223     violates_taint(sub { system $TAINT }, 'system');
1224
1225     $foo = "*";
1226     taint_these $foo;
1227
1228     violates_taint(sub { `$echo 1$foo` }, '``', 'backticks');
1229
1230     SKIP: {
1231         # wildcard expansion doesn't invoke shell on VMS, so is safe
1232         skip "This is not VMS", 2 unless $Is_VMS;
1233     
1234         isnt(join('', eval { glob $foo } ), '', 'globbing');
1235         is($@, '');
1236     }
1237 }
1238
1239 # Operations which affect processes can't use tainted data.
1240 {
1241     violates_taint(sub { kill 0, $TAINT }, 'kill');
1242
1243     SKIP: {
1244         skip "setpgrp() is not available", 2 unless $Config{d_setpgrp};
1245
1246         violates_taint(sub { setpgrp 0, $TAINT0 }, 'setpgrp');
1247     }
1248
1249     SKIP: {
1250         skip "setpriority() is not available", 2 unless $Config{d_setprior};
1251
1252         violates_taint(sub { setpriority 0, $TAINT0, $TAINT0 }, 'setpriority');
1253     }
1254 }
1255
1256 # Some miscellaneous operations can't use tainted data.
1257 {
1258     SKIP: {
1259         skip "syscall() is not available", 2 unless $Config{d_syscall};
1260
1261         violates_taint(sub { syscall $TAINT }, 'syscall');
1262     }
1263
1264     {
1265         my $foo = "x" x 979;
1266         taint_these $foo;
1267         local *FOO;
1268         my $temp = tempfile();
1269         ok(open FOO, "> $temp") or diag("Couldn't open $temp for write: $!");
1270         violates_taint(sub { ioctl FOO, $TAINT0, $foo }, 'ioctl');
1271
1272         my $temp2 = tempfile();
1273         ok(open my $fh, '>', $temp2) or diag("Couldn't open $temp2 for write: $!");
1274         violates_taint(sub { ioctl $fh, $TAINT0, $foo }, 'ioctl');
1275
1276         SKIP: {
1277             skip "fcntl() is not available", 4 unless $Config{d_fcntl};
1278
1279             violates_taint(sub { fcntl FOO, $TAINT0, $foo }, 'fcntl');
1280             violates_taint(sub { fcntl $fh, $TAINT0, $foo }, 'fcntl');
1281         }
1282
1283         close FOO;
1284     }
1285 }
1286
1287 # Some tests involving references
1288 {
1289     my $foo = 'abc' . $TAINT;
1290     my $fooref = \$foo;
1291     isnt_tainted($fooref);
1292     is_tainted($$fooref);
1293     is_tainted($foo);
1294 }
1295
1296 # Some tests involving assignment
1297 {
1298     my $foo = $TAINT0;
1299     my $bar = $foo;
1300     is_tainted($foo);
1301     is_tainted($bar);
1302     is_tainted($foo = $bar);
1303     is_tainted($bar = $bar);
1304     is_tainted($bar += $bar);
1305     is_tainted($bar -= $bar);
1306     is_tainted($bar *= $bar);
1307     is_tainted($bar++);
1308     is_tainted($bar /= $bar);
1309     is_tainted($bar += 0);
1310     is_tainted($bar -= 2);
1311     is_tainted($bar *= -1);
1312     is_tainted($bar /= 1);
1313     is_tainted($bar--);
1314     is($bar, 0);
1315 }
1316
1317 # Test assignment and return of lists
1318 {
1319     my @foo = ("A", "tainted" . $TAINT, "B");
1320     isnt_tainted($foo[0]);
1321     is_tainted(    $foo[1]);
1322     isnt_tainted($foo[2]);
1323     my @bar = @foo;
1324     isnt_tainted($bar[0]);
1325     is_tainted(    $bar[1]);
1326     isnt_tainted($bar[2]);
1327     my @baz = eval { "A", "tainted" . $TAINT, "B" };
1328     isnt_tainted($baz[0]);
1329     is_tainted(    $baz[1]);
1330     isnt_tainted($baz[2]);
1331     my @plugh = eval q[ "A", "tainted" . $TAINT, "B" ];
1332     isnt_tainted($plugh[0]);
1333     is_tainted(    $plugh[1]);
1334     isnt_tainted($plugh[2]);
1335     my $nautilus = sub { "A", "tainted" . $TAINT, "B" };
1336     isnt_tainted(((&$nautilus)[0]));
1337     is_tainted(    ((&$nautilus)[1]));
1338     isnt_tainted(((&$nautilus)[2]));
1339     my @xyzzy = &$nautilus;
1340     isnt_tainted($xyzzy[0]);
1341     is_tainted(    $xyzzy[1]);
1342     isnt_tainted($xyzzy[2]);
1343     my $red_october = sub { return "A", "tainted" . $TAINT, "B" };
1344     isnt_tainted(((&$red_october)[0]));
1345     is_tainted(    ((&$red_october)[1]));
1346     isnt_tainted(((&$red_october)[2]));
1347     my @corge = &$red_october;
1348     isnt_tainted($corge[0]);
1349     is_tainted(    $corge[1]);
1350     isnt_tainted($corge[2]);
1351 }
1352
1353 # Test for system/library calls returning string data of dubious origin.
1354 {
1355     # No reliable %Config check for getpw*
1356     SKIP: {
1357         skip "getpwent() is not available", 9 unless 
1358           eval { setpwent(); getpwent() };
1359
1360         setpwent();
1361         my @getpwent = getpwent();
1362         die "getpwent: $!\n" unless (@getpwent);
1363         isnt_tainted($getpwent[0]);
1364         is_tainted($getpwent[1]);
1365         isnt_tainted($getpwent[2]);
1366         isnt_tainted($getpwent[3]);
1367         isnt_tainted($getpwent[4]);
1368         isnt_tainted($getpwent[5]);
1369         is_tainted($getpwent[6], 'ge?cos');
1370         isnt_tainted($getpwent[7]);
1371         is_tainted($getpwent[8], 'shell');
1372         endpwent();
1373     }
1374
1375     SKIP: {
1376         # pretty hard to imagine not
1377         skip "readdir() is not available", 1 unless $Config{d_readdir};
1378
1379         opendir my $dh, "op" or die "opendir: $!\n";
1380         my $readdir = readdir $dh;
1381         is_tainted($readdir);
1382         closedir $dh;
1383     }
1384
1385     SKIP: {
1386         skip "readlink() or symlink() is not available" unless 
1387           $Config{d_readlink} && $Config{d_symlink};
1388
1389         my $symlink = "sl$$";
1390         unlink($symlink);
1391         my $sl = "/something/naughty";
1392         # it has to be a real path on Mac OS
1393         symlink($sl, $symlink) or die "symlink: $!\n";
1394         my $readlink = readlink($symlink);
1395         is_tainted($readlink);
1396         unlink($symlink);
1397     }
1398 }
1399
1400 # test bitwise ops (regression bug)
1401 {
1402     my $why = "y";
1403     my $j = "x" | $why;
1404     isnt_tainted($j);
1405     $why = $TAINT."y";
1406     $j = "x" | $why;
1407     is_tainted(    $j);
1408 }
1409
1410 # test target of substitution (regression bug)
1411 {
1412     my $why = $TAINT."y";
1413     $why =~ s/y/z/;
1414     is_tainted(    $why);
1415
1416     my $z = "[z]";
1417     $why =~ s/$z/zee/;
1418     is_tainted(    $why);
1419
1420     $why =~ s/e/'-'.$$/ge;
1421     is_tainted(    $why);
1422 }
1423
1424
1425 SKIP: {
1426     skip "no IPC::SysV", 2 unless $ipcsysv;
1427
1428     # test shmread
1429     SKIP: {
1430         skip "shm*() not available", 1 unless $Config{d_shm};
1431
1432         no strict 'subs';
1433         my $sent = "foobar";
1434         my $rcvd;
1435         my $size = 2000;
1436         my $id = shmget(IPC_PRIVATE, $size, S_IRWXU);
1437
1438         if (defined $id) {
1439             if (shmwrite($id, $sent, 0, 60)) {
1440                 if (shmread($id, $rcvd, 0, 60)) {
1441                     substr($rcvd, index($rcvd, "\0")) = '';
1442                 } else {
1443                     warn "# shmread failed: $!\n";
1444                 }
1445             } else {
1446                 warn "# shmwrite failed: $!\n";
1447             }
1448             shmctl($id, IPC_RMID, 0) or warn "# shmctl failed: $!\n";
1449         } else {
1450             warn "# shmget failed: $!\n";
1451         }
1452
1453         skip "SysV shared memory operation failed", 1 unless 
1454           $rcvd eq $sent;
1455
1456         is_tainted($rcvd);
1457     }
1458
1459
1460     # test msgrcv
1461     SKIP: {
1462         skip "msg*() not available", 1 unless $Config{d_msg};
1463
1464         no strict 'subs';
1465         my $id = msgget(IPC_PRIVATE, IPC_CREAT | S_IRWXU);
1466
1467         my $sent      = "message";
1468         my $type_sent = 1234;
1469         my $rcvd;
1470         my $type_rcvd;
1471
1472         if (defined $id) {
1473             if (msgsnd($id, pack("l! a*", $type_sent, $sent), IPC_NOWAIT)) {
1474                 if (msgrcv($id, $rcvd, 60, 0, IPC_NOWAIT)) {
1475                     ($type_rcvd, $rcvd) = unpack("l! a*", $rcvd);
1476                 } else {
1477                     warn "# msgrcv failed: $!\n";
1478                 }
1479             } else {
1480                 warn "# msgsnd failed: $!\n";
1481             }
1482             msgctl($id, IPC_RMID, 0) or warn "# msgctl failed: $!\n";
1483         } else {
1484             warn "# msgget failed\n";
1485         }
1486
1487         SKIP: {
1488             skip "SysV message queue operation failed", 1
1489               unless $rcvd eq $sent && $type_sent == $type_rcvd;
1490
1491             is_tainted($rcvd);
1492         }
1493     }
1494 }
1495
1496 {
1497     # bug id 20001004.006
1498
1499     open my $fh, '<', $TEST or warn "$0: cannot read $TEST: $!" ;
1500     local $/;
1501     my $a = <$fh>;
1502     my $b = <$fh>;
1503
1504     is_tainted($a);
1505     is_tainted($b);
1506     is($b, undef);
1507 }
1508
1509 {
1510     # bug id 20001004.007
1511
1512     open my $fh, '<', $TEST or warn "$0: cannot read $TEST: $!" ;
1513     my $a = <$fh>;
1514
1515     my $c = { a => 42,
1516               b => $a };
1517
1518     isnt_tainted($c->{a});
1519     is_tainted($c->{b});
1520
1521
1522     my $d = { a => $a,
1523               b => 42 };
1524     is_tainted($d->{a});
1525     isnt_tainted($d->{b});
1526
1527
1528     my $e = { a => 42,
1529               b => { c => $a, d => 42 } };
1530     isnt_tainted($e->{a});
1531     isnt_tainted($e->{b});
1532     is_tainted($e->{b}->{c});
1533     isnt_tainted($e->{b}->{d});
1534 }
1535
1536 {
1537     # bug id 20010519.003
1538
1539     BEGIN {
1540         use vars qw($has_fcntl);
1541         eval { require Fcntl; import Fcntl; };
1542         unless ($@) {
1543             $has_fcntl = 1;
1544         }
1545     }
1546
1547     SKIP: {
1548         skip "no Fcntl", 18 unless $has_fcntl;
1549
1550         my $foo = tempfile();
1551         my $evil = $foo . $TAINT;
1552
1553         is(eval { sysopen(my $ro, $evil, &O_RDONLY) }, undef);
1554         is($@, '');
1555
1556         violates_taint(sub { sysopen(my $wo, $evil, &O_WRONLY) }, 'sysopen');
1557         violates_taint(sub { sysopen(my $rw, $evil, &O_RDWR) }, 'sysopen');
1558         violates_taint(sub { sysopen(my $ap, $evil, &O_APPEND) }, 'sysopen');
1559         violates_taint(sub { sysopen(my $cr, $evil, &O_CREAT) }, 'sysopen');
1560         violates_taint(sub { sysopen(my $tr, $evil, &O_TRUNC) }, 'sysopen');
1561
1562         is(eval { sysopen(my $ro, $foo, &O_RDONLY | $TAINT0) }, undef);
1563         is($@, '');
1564
1565         violates_taint(sub { sysopen(my $wo, $foo, &O_WRONLY | $TAINT0) }, 'sysopen');
1566         violates_taint(sub { sysopen(my $rw, $foo, &O_RDWR | $TAINT0) }, 'sysopen');
1567         violates_taint(sub { sysopen(my $ap, $foo, &O_APPEND | $TAINT0) }, 'sysopen');
1568         violates_taint(sub { sysopen(my $cr, $foo, &O_CREAT | $TAINT0) }, 'sysopen');
1569         violates_taint(sub { sysopen(my $tr, $foo, &O_TRUNC | $TAINT0) }, 'sysopen');
1570         is(eval { sysopen(my $ro, $foo, &O_RDONLY, $TAINT0) }, undef);
1571         is($@, '');
1572
1573         violates_taint(sub { sysopen(my $wo, $foo, &O_WRONLY, $TAINT0) }, 'sysopen');
1574         violates_taint(sub { sysopen(my $rw, $foo, &O_RDWR, $TAINT0) }, 'sysopen');
1575         violates_taint(sub { sysopen(my $ap, $foo, &O_APPEND, $TAINT0) }, 'sysopen');
1576         violates_taint(sub { sysopen(my $cr, $foo, &O_CREAT, $TAINT0) }, 'sysopen');
1577         violates_taint(sub { sysopen(my $tr, $foo, &O_TRUNC, $TAINT0) }, 'sysopen');
1578     }
1579 }
1580
1581 {
1582     # bug 20010526.004
1583
1584     use warnings;
1585
1586     my $saw_warning = 0;
1587     local $SIG{__WARN__} = sub { ++$saw_warning };
1588
1589     sub fmi {
1590         my $divnum = shift()/1;
1591         sprintf("%1.1f\n", $divnum);
1592     }
1593
1594     fmi(21 . $TAINT);
1595     fmi(37);
1596     fmi(248);
1597
1598     is($saw_warning, 0);
1599 }
1600
1601
1602 {
1603     # Bug ID 20010730.010
1604
1605     my $i = 0;
1606
1607     sub Tie::TIESCALAR {
1608         my $class =  shift;
1609         my $arg   =  shift;
1610
1611         bless \$arg => $class;
1612     }
1613
1614     sub Tie::FETCH {
1615         $i ++;
1616         ${$_ [0]}
1617     }
1618
1619  
1620     package main;
1621  
1622     my $bar = "The Big Bright Green Pleasure Machine";
1623     taint_these $bar;
1624     tie my ($foo), Tie => $bar;
1625
1626     my $baz = $foo;
1627
1628     ok $i == 1;
1629 }
1630
1631 {
1632     # Check that all environment variables are tainted.
1633     my @untainted;
1634     while (my ($k, $v) = each %ENV) {
1635         if (!tainted($v) &&
1636             # These we have explicitly untainted or set earlier.
1637             $k !~ /^(BASH_ENV|CDPATH|ENV|IFS|PATH|PERL_CORE|TEMP|TERM|TMP)$/) {
1638             push @untainted, "# '$k' = '$v'\n";
1639         }
1640     }
1641     is("@untainted", "");
1642 }
1643
1644
1645 is(${^TAINT}, 1, '$^TAINT is on');
1646
1647 eval { ${^TAINT} = 0 };
1648 is(${^TAINT}, 1, '$^TAINT is not assignable');
1649 like($@, qr/^Modification of a read-only value attempted/,
1650      'Assigning to ${^TAINT} fails');
1651
1652 {
1653     # bug 20011111.105
1654     
1655     my $re1 = qr/x$TAINT/;
1656     is_tainted($re1);
1657     
1658     my $re2 = qr/^$re1\z/;
1659     is_tainted($re2);
1660     
1661     my $re3 = "$re2";
1662     is_tainted($re3);
1663 }
1664
1665 SKIP: {
1666     skip "system {} has different semantics on Win32", 1 if $Is_MSWin32;
1667
1668     # bug 20010221.005
1669     local $ENV{PATH} .= $TAINT;
1670     eval { system { "echo" } "/arg0", "arg1" };
1671     like($@, qr/^Insecure \$ENV/);
1672 }
1673
1674 TODO: {
1675     todo_skip 'tainted %ENV warning occludes tainted arguments warning', 22
1676       if $Is_VMS;
1677
1678     # bug 20020208.005 plus some single arg exec/system extras
1679     violates_taint(sub { exec $TAINT, $TAINT }, 'exec');
1680     violates_taint(sub { exec $TAINT $TAINT }, 'exec');
1681     violates_taint(sub { exec $TAINT $TAINT, $TAINT }, 'exec');
1682     violates_taint(sub { exec $TAINT 'notaint' }, 'exec');
1683     violates_taint(sub { exec {'notaint'} $TAINT }, 'exec');
1684
1685     violates_taint(sub { system $TAINT, $TAINT }, 'system');
1686     violates_taint(sub { system $TAINT $TAINT }, 'system');
1687     violates_taint(sub { system $TAINT $TAINT, $TAINT }, 'system');
1688     violates_taint(sub { system $TAINT 'notaint' }, 'system');
1689     violates_taint(sub { system {'notaint'} $TAINT }, 'system');
1690
1691     eval { 
1692         no warnings;
1693         system("lskdfj does not exist","with","args"); 
1694     };
1695     is($@, "");
1696
1697     eval {
1698         no warnings;
1699         exec("lskdfj does not exist","with","args"); 
1700     };
1701     is($@, "");
1702
1703     # If you add tests here update also the above skip block for VMS.
1704 }
1705
1706 {
1707     # [ID 20020704.001] taint propagation failure
1708     use re 'taint';
1709     $TAINT =~ /(.*)/;
1710     is_tainted(my $foo = $1);
1711 }
1712
1713 {
1714     # [perl #24291] this used to dump core
1715     our %nonmagicalenv = ( PATH => "util" );
1716     local *ENV = \%nonmagicalenv;
1717     eval { system("lskdfj"); };
1718     like($@, qr/^%ENV is aliased to another variable while running with -T switch/);
1719     local *ENV = *nonmagicalenv;
1720     eval { system("lskdfj"); };
1721     like($@, qr/^%ENV is aliased to %nonmagicalenv while running with -T switch/);
1722 }
1723 {
1724     # [perl #24248]
1725     $TAINT =~ /(.*)/;
1726     isnt_tainted($1);
1727     my $notaint = $1;
1728     isnt_tainted($notaint);
1729
1730     my $l;
1731     $notaint =~ /($notaint)/;
1732     $l = $1;
1733     isnt_tainted($1);
1734     isnt_tainted($l);
1735     $notaint =~ /($TAINT)/;
1736     $l = $1;
1737     is_tainted($1);
1738     is_tainted($l);
1739
1740     $TAINT =~ /($notaint)/;
1741     $l = $1;
1742     isnt_tainted($1);
1743     isnt_tainted($l);
1744     $TAINT =~ /($TAINT)/;
1745     $l = $1;
1746     is_tainted($1);
1747     is_tainted($l);
1748
1749     my $r;
1750     ($r = $TAINT) =~ /($notaint)/;
1751     isnt_tainted($1);
1752     ($r = $TAINT) =~ /($TAINT)/;
1753     is_tainted($1);
1754
1755     {
1756         use re 'eval'; # this shouldn't make any difference
1757         ($r = $TAINT) =~ /($notaint)/;
1758         isnt_tainted($1);
1759         ($r = $TAINT) =~ /($TAINT)/;
1760         is_tainted($1);
1761     }
1762
1763     #  [perl #24674]
1764     # accessing $^O  shoudn't taint it as a side-effect;
1765     # assigning tainted data to it is now an error
1766
1767     isnt_tainted($^O);
1768     if (!$^X) { } elsif ($^O eq 'bar') { }
1769     isnt_tainted($^O);
1770     local $^O;  # We're going to clobber something test infrastructure depends on.
1771     eval '$^O = $^X';
1772     like($@, qr/Insecure dependency in/);
1773 }
1774
1775 EFFECTIVELY_CONSTANTS: {
1776     my $tainted_number = 12 + $TAINT0;
1777     is_tainted( $tainted_number );
1778
1779     # Even though it's always 0, it's still tainted
1780     my $tainted_product = $tainted_number * 0;
1781     is_tainted( $tainted_product );
1782     is($tainted_product, 0);
1783 }
1784
1785 TERNARY_CONDITIONALS: {
1786     my $tainted_true  = $TAINT . "blah blah blah";
1787     my $tainted_false = $TAINT0;
1788     is_tainted( $tainted_true );
1789     is_tainted( $tainted_false );
1790
1791     my $result = $tainted_true ? "True" : "False";
1792     is($result, "True");
1793     isnt_tainted( $result );
1794
1795     $result = $tainted_false ? "True" : "False";
1796     is($result, "False");
1797     isnt_tainted( $result );
1798
1799     my $untainted_whatever = "The Fabulous Johnny Cash";
1800     my $tainted_whatever = "Soft Cell" . $TAINT;
1801
1802     $result = $tainted_true ? $tainted_whatever : $untainted_whatever;
1803     is($result, "Soft Cell");
1804     is_tainted( $result );
1805
1806     $result = $tainted_false ? $tainted_whatever : $untainted_whatever;
1807     is($result, "The Fabulous Johnny Cash");
1808     isnt_tainted( $result );
1809 }
1810
1811 {
1812     # rt.perl.org 5900  $1 remains tainted if...
1813     # 1) The regular expression contains a scalar variable AND
1814     # 2) The regular expression appears in an elsif clause
1815
1816     my $foo = "abcdefghi" . $TAINT;
1817
1818     my $valid_chars = 'a-z';
1819     if ( $foo eq '' ) {
1820     }
1821     elsif ( $foo =~ /([$valid_chars]+)/o ) {
1822         isnt_tainted($1);
1823         isnt($1, undef);
1824     }
1825
1826     if ( $foo eq '' ) {
1827     }
1828     elsif ( my @bar = $foo =~ /([$valid_chars]+)/o ) {
1829         isnt_tainted($bar[0]);
1830         is(scalar @bar, 1);
1831     }
1832 }
1833
1834 # at scope exit, a restored localised value should have its old
1835 # taint status, not the taint status of the current statement
1836
1837 {
1838     our $x99 = $^X;
1839     is_tainted($x99);
1840
1841     $x99 = '';
1842     isnt_tainted($x99);
1843
1844     my $c = do { local $x99; $^X };
1845     isnt_tainted($x99);
1846 }
1847 {
1848     our $x99 = $^X;
1849     is_tainted($x99);
1850
1851     my $c = do { local $x99; '' };
1852     is_tainted($x99);
1853 }
1854
1855 # an mg_get of a tainted value during localization shouldn't taint the
1856 # statement
1857
1858 {
1859     eval { local $0, eval '1' };
1860     is($@, '');
1861 }
1862
1863 # [perl #8262] //g loops infinitely on tainted data
1864
1865 {
1866     my @a;
1867     $a[0] = $^X . '-';
1868     $a[0]=~ m/(.)/g;
1869     cmp_ok pos($a[0]), '>', 0, "infinite m//g on arrays (aelemfast)";
1870
1871     my $i = 1;
1872     $a[$i] = $^X . '-';
1873     $a[$i]=~ m/(.)/g;
1874     cmp_ok pos($a[$i]), '>', 0, "infinite m//g on arrays (aelem)";
1875
1876     my %h;
1877     $h{a} = $^X . '-';
1878     $h{a}=~ m/(.)/g;
1879     cmp_ok pos($h{a}), '>', 0, "infinite m//g on hashes (helem)";
1880 }
1881
1882 SKIP:
1883 {
1884     my $got_dualvar;
1885     eval 'use Scalar::Util "dualvar"; $got_dualvar++';
1886     skip "No Scalar::Util::dualvar" unless $got_dualvar;
1887     my $a = Scalar::Util::dualvar(3, $^X);
1888     my $b = $a + 5;
1889     is ($b, 8, "Arithmetic on tainted dualvars works");
1890 }
1891
1892 # opening '|-' should not trigger $ENV{PATH} check
1893
1894 {
1895     SKIP: {
1896         skip "fork() is not available", 3 unless $Config{'d_fork'};
1897         skip "opening |- is not stable on threaded Open/MirBSD with taint", 3
1898             if $Config{useithreads} and $Is_OpenBSD || $Is_MirBSD;
1899
1900         $ENV{'PATH'} = $TAINT;
1901         local $SIG{'PIPE'} = 'IGNORE';
1902         eval {
1903             my $pid = open my $pipe, '|-';
1904             if (!defined $pid) {
1905                 die "open failed: $!";
1906             }
1907             if (!$pid) {
1908                 kill 'KILL', $$;        # child suicide
1909             }
1910             close $pipe;
1911         };
1912         unlike($@, qr/Insecure \$ENV/, 'fork triggers %ENV check');
1913         is($@, '',               'pipe/fork/open/close failed');
1914         eval {
1915             open my $pipe, "|$Invoke_Perl -e 1";
1916             close $pipe;
1917         };
1918         like($@, qr/Insecure \$ENV/, 'popen neglects %ENV check');
1919     }
1920 }
1921
1922 {
1923     package AUTOLOAD_TAINT;
1924     sub AUTOLOAD {
1925         our $AUTOLOAD;
1926         return if $AUTOLOAD =~ /DESTROY/;
1927         if ($AUTOLOAD =~ /untainted/) {
1928             main::isnt_tainted($AUTOLOAD, '$AUTOLOAD can be untainted');
1929             my $copy = $AUTOLOAD;
1930             main::isnt_tainted($copy, '$AUTOLOAD can be untainted');
1931         } else {
1932             main::is_tainted($AUTOLOAD, '$AUTOLOAD can be tainted');
1933             my $copy = $AUTOLOAD;
1934             main::is_tainted($copy, '$AUTOLOAD can be tainted');
1935         }
1936     }
1937
1938     package main;
1939     my $o = bless [], 'AUTOLOAD_TAINT';
1940     $o->untainted;
1941     $o->$TAINT;
1942     $o->untainted;
1943 }
1944
1945 {
1946     # tests for tainted format in s?printf
1947     my $fmt = $TAINT . "# %s\n";
1948     violates_taint(sub { printf($fmt, "foo") }, 'printf',
1949                    q/printf doesn't like tainted formats/);
1950     violates_taint(sub { printf($TAINT . "# %s\n", "foo") }, 'printf',
1951                    q/printf doesn't like tainted format expressions/);
1952     eval { printf("# %s\n", $TAINT . "foo") };
1953     is($@, '', q/printf accepts other tainted args/);
1954     violates_taint(sub { sprintf($fmt, "foo") }, 'sprintf',
1955                    q/sprintf doesn't like tainted formats/);
1956     violates_taint(sub { sprintf($TAINT . "# %s\n", "foo") }, 'sprintf',
1957                    q/sprintf doesn't like tainted format expressions/);
1958     eval { sprintf("# %s\n", $TAINT . "foo") };
1959     is($@, '', q/sprintf accepts other tainted args/);
1960 }
1961
1962 {
1963     # 40708
1964     my $n  = 7e9;
1965     8e9 - $n;
1966
1967     my $val = $n;
1968     is ($val, '7000000000', 'Assignment to untainted variable');
1969     $val = $TAINT;
1970     $val = $n;
1971     is ($val, '7000000000', 'Assignment to tainted variable');
1972 }
1973
1974 {
1975     my $val = 0;
1976     my $tainted = '1' . $TAINT;
1977     eval '$val = eval $tainted;';
1978     is ($val, 0, "eval doesn't like tainted strings");
1979     like ($@, qr/^Insecure dependency in eval/);
1980
1981     # Rather nice code to get a tainted undef by from Rick Delaney
1982     open my $fh, "test.pl" or die $!;
1983     seek $fh, 0, 2 or die $!;
1984     $tainted = <$fh>;
1985
1986     eval 'eval $tainted';
1987     like ($@, qr/^Insecure dependency in eval/);
1988 }
1989
1990 foreach my $ord (78, 163, 256) {
1991     # 47195
1992     my $line = 'A1' . $TAINT . chr $ord;
1993     chop $line;
1994     is($line, 'A1');
1995     $line =~ /(A\S*)/;
1996     isnt_tainted($1, "\\S match with chr $ord");
1997 }
1998
1999 {
2000   SKIP: {
2001       skip 'No crypt function, skipping crypt tests', 4 if(!$Config{d_crypt});
2002       # 59998
2003       sub cr { my $x = crypt($_[0], $_[1]); $x }
2004       sub co { my $x = ~$_[0]; $x }
2005       my ($a, $b);
2006       $a = cr('hello', 'foo' . $TAINT);
2007       $b = cr('hello', 'foo');
2008       is_tainted($a,  "tainted crypt");
2009       isnt_tainted($b, "untainted crypt");
2010       $a = co('foo' . $TAINT);
2011       $b = co('foo');
2012       is_tainted($a,  "tainted complement");
2013       isnt_tainted($b, "untainted complement");
2014     }
2015 }
2016
2017 {
2018     my @data = qw(bonk zam zlonk qunckkk);
2019     # Clearly some sort of usenet bang-path
2020     my $string = $TAINT . join "!", @data;
2021
2022     is_tainted($string, "tainted data");
2023
2024     my @got = split /!|,/, $string;
2025
2026     # each @got would be useful here, but I want the test for earlier perls
2027     for my $i (0 .. $#data) {
2028         is_tainted($got[$i], "tainted result $i");
2029         is($got[$i], $data[$i], "correct content $i");
2030     }
2031
2032     is_tainted($string, "still tainted data");
2033
2034     my @got = split /[!,]/, $string;
2035
2036     # each @got would be useful here, but I want the test for earlier perls
2037     for my $i (0 .. $#data) {
2038         is_tainted($got[$i], "tainted result $i");
2039         is($got[$i], $data[$i], "correct content $i");
2040     }
2041
2042     is_tainted($string, "still tainted data");
2043
2044     my @got = split /!/, $string;
2045
2046     # each @got would be useful here, but I want the test for earlier perls
2047     for my $i (0 .. $#data) {
2048         is_tainted($got[$i], "tainted result $i");
2049         is($got[$i], $data[$i], "correct content $i");
2050     }
2051 }
2052
2053 # Bug RT #52552 - broken by change at git commit id f337b08
2054 {
2055     my $x = $TAINT. q{print "Hello world\n"};
2056     my $y = pack "a*", $x;
2057     is_tainted($y, "pack a* preserves tainting");
2058
2059     my $z = pack "A*", q{print "Hello world\n"}.$TAINT;
2060     is_tainted($z, "pack A* preserves tainting");
2061
2062     my $zz = pack "a*a*", q{print "Hello world\n"}, $TAINT;
2063     is_tainted($zz, "pack a*a* preserves tainting");
2064 }
2065
2066 # Bug RT #61976 tainted $! would show numeric rather than string value
2067
2068 {
2069     my $tainted_path = substr($^X,0,0) . "/no/such/file";
2070     my $err;
2071     # $! is used in a tainted expression, so gets tainted
2072     open my $fh, $tainted_path or $err= "$!";
2073     unlike($err, qr/^\d+$/, 'tainted $!');
2074 }
2075
2076 {
2077     # #6758: tainted values become untainted in tied hashes
2078     #         (also applies to other value magic such as pos)
2079
2080
2081     package P6758;
2082
2083     sub TIEHASH { bless {} }
2084     sub TIEARRAY { bless {} }
2085
2086     my $i = 0;
2087
2088     sub STORE {
2089         main::is_tainted($_[1], "tied arg1 tainted");
2090         main::is_tainted($_[2], "tied arg2 tainted");
2091         $i++;
2092     }
2093
2094     package main;
2095
2096     my ($k,$v) = qw(1111 val);
2097     taint_these($k,$v);
2098     tie my @array, 'P6758';
2099     tie my %hash , 'P6758';
2100     $array[$k] = $v;
2101     $hash{$k} = $v;
2102     ok $i == 2, "tied STORE called correct number of times";
2103 }
2104
2105 # Bug RT #45167 the return value of sprintf sometimes wasn't tainted
2106 # when the args were tainted. This only occured on the first use of
2107 # sprintf; after that, its TARG has taint magic attached, so setmagic
2108 # at the end works.  That's why there are multiple sprintf's below, rather
2109 # than just one wrapped in an inner loop. Also, any plaintext between
2110 # fprmat entires would correctly cause tainting to get set. so test with
2111 # "%s%s" rather than eg "%s %s".
2112
2113 {
2114     for my $var1 ($TAINT, "123") {
2115         for my $var2 ($TAINT0, "456") {
2116             is( tainted(sprintf '%s', $var1, $var2), tainted($var1),
2117                 "sprintf '%s', '$var1', '$var2'" );
2118             is( tainted(sprintf ' %s', $var1, $var2), tainted($var1),
2119                 "sprintf ' %s', '$var1', '$var2'" );
2120             is( tainted(sprintf '%s%s', $var1, $var2),
2121                 tainted($var1) || tainted($var2),
2122                 "sprintf '%s%s', '$var1', '$var2'" );
2123         }
2124     }
2125 }
2126
2127
2128 # Bug RT #67962: old tainted $1 gets treated as tainted
2129 # in next untainted # match
2130
2131 {
2132     use re 'taint';
2133     "abc".$TAINT =~ /(.*)/; # make $1 tainted
2134     is_tainted($1, '$1 should be tainted');
2135
2136     my $untainted = "abcdef";
2137     isnt_tainted($untainted, '$untainted should be untainted');
2138     $untainted =~ s/(abc)/$1/;
2139     isnt_tainted($untainted, '$untainted should still be untainted');
2140     $untainted =~ s/(abc)/x$1/;
2141     isnt_tainted($untainted, '$untainted should yet still be untainted');
2142 }
2143
2144 {
2145     # On Windows we can't spawn a fresh Perl interpreter unless at
2146     # least the Windows system directory (usually C:\Windows\System32)
2147     # is still on the PATH.  There is however no way to determine the
2148     # actual path on the current system without loading the Win32
2149     # module, so we just restore the original $ENV{PATH} here.
2150     local $ENV{PATH} = $ENV{PATH};
2151     $ENV{PATH} = $old_env_path if $Is_MSWin32;
2152
2153     fresh_perl_is(<<'end', "ok", { switches => [ '-T' ] },
2154     $TAINT = substr($^X, 0, 0);
2155     formline('@'.('<'x("2000".$TAINT)).' | @*', 'hallo', 'welt');
2156     print "ok";
2157 end
2158     "formline survives a tainted dynamic picture");
2159 }
2160
2161 {
2162     isnt_tainted($^A, "format accumulator not tainted yet");
2163     formline('@ | @*', 'hallo' . $TAINT, 'welt');
2164     is_tainted($^A, "tainted formline argument makes a tainted accumulator");
2165     $^A = "";
2166     isnt_tainted($^A, "accumulator can be explicitly untainted");
2167     formline('@' .('<'*5) . ' | @*', 'hallo', 'welt');
2168     isnt_tainted($^A, "accumulator still untainted");
2169     $^A = "" . $TAINT;
2170     is_tainted($^A, "accumulator can be explicitly tainted");
2171     formline('@' .('<'*5) . ' | @*', 'hallo', 'welt');
2172     is_tainted($^A, "accumulator still tainted");
2173     $^A = "";
2174     isnt_tainted($^A, "accumulator untainted again");
2175     formline('@' .('<'*5) . ' | @*', 'hallo', 'welt');
2176     isnt_tainted($^A, "accumulator still untainted");
2177     formline('@' .('<'*(5+$TAINT0)) . ' | @*', 'hallo', 'welt');
2178     is_tainted($^A, "the accumulator should be tainted already");
2179     is_tainted($^A, "tainted formline picture makes a tainted accumulator");
2180 }
2181
2182 {   # Bug #80610
2183     "Constant(1)" =~ / ^ ([a-z_]\w*) (?: [(] (.*) [)] )? $ /xi;
2184     my $a = $1;
2185     my $b = $2;
2186     isnt_tainted($a, "regex optimization of single char /[]/i doesn't taint");
2187     isnt_tainted($b, "regex optimization of single char /[]/i doesn't taint");
2188 }
2189
2190 {
2191     # RT 81230: tainted value during FETCH created extra ref to tied obj
2192
2193     package P81230;
2194     use warnings;
2195
2196     my %h;
2197
2198     sub TIEHASH {
2199         my $x = $^X; # tainted
2200         bless  \$x;
2201     }
2202     sub FETCH { my $x = $_[0]; $$x . "" }
2203
2204     tie %h, 'P81230';
2205
2206     my $w = "";
2207     local $SIG{__WARN__} = sub { $w .= "@_" };
2208
2209     untie %h if $h{"k"};
2210
2211     ::is($w, "", "RT 81230");
2212 }
2213
2214 {
2215     # Compiling a subroutine inside a tainted expression does not make the
2216     # constant folded values tainted.
2217     my $x = sub { "x" . "y" };
2218     my $y = $ENV{PATH} . $x->(); # Compile $x inside a tainted expression
2219     my $z = $x->();
2220     isnt_tainted($z, "Constants folded value not tainted");
2221 }
2222
2223 {
2224     # now that regexes are first class SVs, make sure that they themselves
2225     # as well as references to them are tainted
2226
2227     my $rr = qr/(.)$TAINT/;
2228     my $r = $$rr; # bare REGEX
2229     my $s ="abc";
2230     ok($s =~ s/$r/x/, "match bare regex");
2231     is_tainted($s, "match bare regex taint");
2232     is($s, 'xbc', "match bare regex taint value");
2233 }
2234
2235 {
2236     # [perl #82616] security Issues with user-defined \p{} properties
2237     # A using a tainted user-defined property should croak
2238
2239     sub IsA { sprintf "%02x", ord("A") }
2240
2241     my $prop = "IsA";
2242     ok("A" =~ /\p{$prop}/, "user-defined property: non-tainted case");
2243     $prop = "IsA$TAINT";
2244     eval { "A" =~ /\p{$prop}/};
2245     like($@, qr/Insecure user-defined property \\p\{main::IsA}/,
2246             "user-defined property: tainted case");
2247 }
2248
2249 {
2250     # [perl #87336] lc/uc(first) failing to taint the returned string
2251     my $source = "foo$TAINT";
2252     my $dest = lc $source;
2253     is_tainted $dest, "lc(tainted) taints its return value";
2254     $dest = lcfirst $source;
2255     is_tainted $dest, "lcfirst(tainted) taints its return value";
2256     $dest = uc $source;
2257     is_tainted $dest, "uc(tainted) taints its return value";
2258     $dest = ucfirst $source;
2259     is_tainted $dest, "ucfirst(tainted) taints its return value";
2260 }
2261
2262 {
2263     # Taintedness of values returned from given()
2264     use feature 'switch';
2265     no warnings 'experimental::smartmatch';
2266
2267     my @descriptions = ('when', 'given end', 'default');
2268
2269     for (qw<x y z>) {
2270         my $letter = "$_$TAINT";
2271
2272         my $desc = "tainted value returned from " . shift(@descriptions);
2273
2274         my $res = do {
2275             given ($_) {
2276                 when ('x') { $letter }
2277                 when ('y') { goto leavegiven }
2278                 default    { $letter }
2279                 leavegiven:  $letter
2280             }
2281         };
2282         is         $res, $letter, "$desc is correct";
2283         is_tainted $res,          "$desc stays tainted";
2284     }
2285 }
2286
2287
2288 # tainted constants and index()
2289 #  RT 64804; http://bugs.debian.org/291450
2290 {
2291     ok(tainted $old_env_path, "initial taintedness");
2292     BEGIN { no strict 'refs'; my $v = $old_env_path; *{"::C"} = sub () { $v }; }
2293     ok(tainted C, "constant is tainted properly");
2294     ok(!tainted "", "tainting not broken yet");
2295     index(undef, C);
2296     ok(!tainted "", "tainting still works after index() of the constant");
2297 }
2298
2299 # Tainted values with smartmatch
2300 # [perl #93590] S_do_smartmatch stealing its own string buffers
2301 {
2302 no warnings 'experimental::smartmatch';
2303 ok "M$TAINT" ~~ ['m', 'M'], '$tainted ~~ ["whatever", "match"]';
2304 ok !("M$TAINT" ~~ ['m', undef]), '$tainted ~~ ["whatever", undef]';
2305 }
2306
2307 # Tainted values and ref()
2308 for(1,2) {
2309   my $x = bless \"M$TAINT", ref(bless[], "main");
2310 }
2311 pass("no death when TARG of ref is tainted");
2312
2313 # $$ should not be tainted by being read in a tainted expression.
2314 {
2315     isnt_tainted $$, "PID not tainted initially";
2316     my $x = $ENV{PATH}.$$;
2317     isnt_tainted $$, "PID not tainted when read in tainted expression";
2318 }
2319
2320 SKIP: {
2321     skip 'No locale testing without d_setlocale', 4 if(!$Config{d_setlocale});
2322
2323     use feature 'fc';
2324     BEGIN {
2325         if($Config{d_setlocale}) {
2326             require locale; import locale;
2327         }
2328     }
2329     my ($latin1, $utf8) = ("\xDF") x 2;
2330     utf8::downgrade($latin1);
2331     utf8::upgrade($utf8);
2332
2333     is_tainted fc($latin1), "under locale, lc(latin1) taints the result";
2334     is_tainted fc($utf8), "under locale, lc(utf8) taints the result";
2335
2336     is_tainted "\F$latin1", "under locale, \\Flatin1 taints the result";
2337     is_tainted "\F$utf8", "under locale, \\Futf8 taints the result";
2338 }
2339
2340 { # 111654
2341   eval {
2342     eval { die "Test\n".substr($ENV{PATH}, 0, 0); };
2343     die;
2344   };
2345   like($@, qr/^Test\n\t\.\.\.propagated at /, "error should be propagated");
2346 }
2347
2348 # tainted run-time (?{}) should die
2349
2350 {
2351     my $code = '(?{})' . $TAINT;
2352     use re 'eval';
2353     eval { "a" =~ /$code/ };
2354     like($@, qr/Eval-group in insecure regular expression/, "tainted (?{})");
2355 }
2356
2357 # reset() and tainted undef (?!)
2358 $::x = "foo";
2359 $_ = "$TAINT".reset "x";
2360 is eval { eval $::x.1 }, 1, 'reset does not taint undef';
2361
2362 # This may bomb out with the alarm signal so keep it last
2363 SKIP: {
2364     skip "No alarm()"  unless $Config{d_alarm};
2365     # Test from RT #41831]
2366     # [PATCH] Bug & fix: hang when using study + taint mode (perl 5.6.1, 5.8.x)
2367
2368     my $DATA = <<'END' . $TAINT;
2369 line1 is here
2370 line2 is here
2371 line3 is here
2372 line4 is here
2373
2374 END
2375
2376     #study $DATA;
2377
2378     ## don't set $SIG{ALRM}, since we'd never get to a user-level handler as
2379     ## perl is stuck in a regexp infinite loop!
2380
2381     alarm(10);
2382
2383     if ($DATA =~ /^line2.*line4/m) {
2384         fail("Should not be a match")
2385     } else {
2386         pass("Match on tainted multiline data should fail promptly");
2387     }
2388
2389     alarm(0);
2390 }
2391 __END__
2392 # Keep the previous test last