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