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