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