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