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