5 my $symlink_exists = eval { symlink("",""); 1 };
14 for (keys %ENV) { # untaint ENV
15 ($ENV{$_}) = keys %{{ map {$_ => 1} $ENV{$_} }};
18 $SIG{'__WARN__'} = sub { $warn_msg = $_[0]; warn "# Warn: $_[0]"; }
21 if ( $symlink_exists ) { print "1..184\n"; }
22 else { print "1..75\n"; }
30 find({wanted => sub { print "ok 1\n" if $_ eq 'filefind.t'; }, untaint => 1}, ':');
31 finddepth({wanted => sub { print "ok 2\n" if $_ eq 'filefind.t'; }, untaint => 1}, ':');
33 find({wanted => sub { print "ok 1\n" if $_ eq 'filefind.t'; }, untaint => 1,
34 untaint_pattern => qr|^(.+)$|}, '.');
35 finddepth({wanted => sub { print "ok 2\n" if $_ eq 'filefind.t'; },
36 untaint => 1, untaint_pattern => qr|^(.+)$|}, '.');
40 my $FastFileTests_OK = 0;
48 unlink ':fa:fa_ord',':fa:fsl',':fa:faa:faa_ord',
49 ':fa:fab:fab_ord',':fa:fab:faba:faba_ord',
50 ':fb:fb_ord',':fb:fba:fba_ord';
65 unlink 'fa/fa_ord','fa/fsl','fa/faa/faa_ord',
66 'fa/fab/fab_ord','fa/fab/faba/faba_ord',
67 'fb/fb_ord','fb/fba/fba_ord';
86 if ($_[0]) { print "ok $case\n"; }
87 else { print "not ok $case\n"; }
92 if ($_[0]) { print "ok $case\n"; }
93 else { print "not ok $case\n $!\n"; exit 0; }
97 CheckDie( open(my $T,'>',$_[0]) );
101 CheckDie( mkdir($_[0],$_[1]) );
105 print "# '$_' => 1\n";
106 s#\.$## if ($^O eq 'VMS' && $_ ne '.');
107 Check( $Expect{$_} );
108 if ( $FastFileTests_OK ) {
110 unless ( $Expect_Dir{$_} && ! -d _ );
113 unless ( $Expect_Dir{$_} && ! -d $_ );
115 $File::Find::prune=1 if $_ eq 'faba';
120 my $n = $File::Find::name;
121 $n =~ s#\.$## if ($^O eq 'VMS' && $n ne '.');
122 print "# '$n' => 1\n";
123 my $i = rindex($n,'/');
124 my $OK = exists($Expect{$n});
125 unless ($^O eq 'MacOS') {
127 $OK= exists($Expect{substr($n,0,$i)}) if $i >= 0;
135 print "# '$_' => 1\n";
136 s#\.$## if ($^O eq 'VMS' && $_ ne '.');
137 my $i = rindex($_,'/');
138 my $OK = exists($Expect{$_});
139 unless ($^O eq 'MacOS') {
141 $OK= exists($Expect{substr($_,0,$i)}) if $i >= 0;
149 print "# \$File::Find::dir => '$File::Find::dir'\n";
150 print "# \$_ => '$_'\n";
157 print "# --PREPROCESS--\n";
158 print "# \$File::Find::dir => '$File::Find::dir' \n";
159 foreach $file (@files) {
161 delete $Expect{$File::Find::dir}->{$file};
163 print "# --END PREPROCESS--\n";
164 Check(scalar(keys %{$Expect{$File::Find::dir}}) == 0);
165 if (scalar(keys %{$Expect{$File::Find::dir}}) == 0) {
166 delete $Expect{$File::Find::dir}
172 print "# POSTPROCESS: \$File::Find::dir => '$File::Find::dir' \n";
173 delete $Expect{$File::Find::dir};
177 if ($^O eq 'MacOS') {
179 MkDir( 'for_find',0770 );
180 CheckDie(chdir(for_find));
182 $cwd = cwd(); # save cwd
183 ( $cwd_untainted ) = $cwd =~ m|^(.+)$|; # untaint it
188 MkDir( ':fb:fba',0770 );
189 touch(':fb:fba:fba_ord');
190 CheckDie( symlink(':fb',':fa:fsl') ) if $symlink_exists;
193 MkDir( ':fa:faa',0770 );
194 touch(':fa:faa:faa_ord');
195 MkDir( ':fa:fab',0770 );
196 touch(':fa:fab:fab_ord');
197 MkDir( ':fa:fab:faba',0770 );
198 touch(':fa:fab:faba:faba_ord');
200 %Expect = (':' => 1, 'fsl' => 1, 'fa_ord' => 1, 'fab' => 1, 'fab_ord' => 1,
201 'faba' => 1, 'faa' => 1, 'faa_ord' => 1);
202 delete $Expect{'fsl'} unless $symlink_exists;
203 %Expect_Dir = (':' => 1, 'fa' => 1, 'faa' => 1, 'fab' => 1, 'faba' => 1,
204 'fb' => 1, 'fba' => 1);
205 delete @Expect_Dir{'fb','fba'} unless $symlink_exists;
206 File::Find::find( {wanted => \&wanted, untaint => 1},':fa' );
207 Check( scalar(keys %Expect) == 0 );
209 %Expect=(':fa' => 1, ':fa:fsl' => 1, ':fa:fa_ord' => 1, ':fa:fab' => 1,
210 ':fa:fab:fab_ord' => 1, ':fa:fab:faba' => 1,
211 ':fa:fab:faba:faba_ord' => 1, ':fa:faa' => 1, ':fa:faa:faa_ord' => 1);
212 delete $Expect{':fa:fsl'} unless $symlink_exists;
213 %Expect_Dir = (':fa' => 1, ':fa:faa' => 1, ':fa:fab' => 1, ':fa:fab:faba' => 1,
214 ':fb' => 1, ':fb:fba' => 1);
215 delete @Expect_Dir{':fb',':fb:fba'} unless $symlink_exists;
216 File::Find::find( {wanted => \&wanted, no_chdir => 1, untaint => 1},':fa' );
217 Check( scalar(keys %Expect) == 0 );
219 %Expect=(':' => 1, ':fa' => 1, ':fa:fsl' => 1, ':fa:fa_ord' => 1, ':fa:fab' => 1,
220 ':fa:fab:fab_ord' => 1, ':fa:fab:faba' => 1,
221 ':fa:fab:faba:faba_ord' => 1, ':fa:faa' => 1, ':fa:faa:faa_ord' => 1,
222 ':fb' => 1, ':fb:fba' => 1, ':fb:fba:fba_ord' => 1, ':fb:fb_ord' => 1);
223 delete $Expect{':fa:fsl'} unless $symlink_exists;
224 %Expect_Dir = (':' => 1, ':fa' => 1, ':fa:faa' => 1, ':fa:fab' => 1, ':fa:fab:faba' => 1,
225 ':fb' => 1, ':fb:fba' => 1);
226 delete @Expect_Dir{':fb',':fb:fba'} unless $symlink_exists;
227 File::Find::finddepth( {wanted => \&dn_wanted, untaint => 1 },':' );
228 Check( scalar(keys %Expect) == 0 );
230 %Expect=(':' => 1, ':fa' => 1, ':fa:fsl' => 1, ':fa:fa_ord' => 1, ':fa:fab' => 1,
231 ':fa:fab:fab_ord' => 1, ':fa:fab:faba' => 1,
232 ':fa:fab:faba:faba_ord' => 1, ':fa:faa' => 1, ':fa:faa:faa_ord' => 1,
233 ':fb' => 1, ':fb:fba' => 1, ':fb:fba:fba_ord' => 1, ':fb:fb_ord' => 1);
234 delete $Expect{':fa:fsl'} unless $symlink_exists;
235 %Expect_Dir = (':' => 1, ':fa' => 1, ':fa:faa' => 1, ':fa:fab' => 1, ':fa:fab:faba' => 1,
236 ':fb' => 1, ':fb:fba' => 1);
237 delete @Expect_Dir{':fb',':fb:fba'} unless $symlink_exists;
238 File::Find::finddepth( {wanted => \&d_wanted, no_chdir => 1, untaint => 1 },':' );
239 Check( scalar(keys %Expect) == 0 );
241 # untaint, preprocess and postprocess tests below added by Thomas Wegner, 17-05-2001
243 print "# check untainting (no follow)\n";
244 # don't untaint at all
246 eval {File::Find::find( {wanted => \&simple_wanted},':fa' );};
248 Check( $@ =~ m|Insecure dependency| );
249 chdir($cwd_untainted);
252 eval {File::Find::find( {wanted => \&simple_wanted, untaint => 1,
253 untaint_pattern => qr|^(NO_MATCH)$|},':fa' );};
255 Check( $@ =~ m|is still tainted| );
256 chdir($cwd_untainted);
258 print "# check untaint_skip (no follow)\n";
260 eval {File::Find::find( {wanted => \&simple_wanted, untaint => 1, untaint_skip => 1,
261 untaint_pattern => qr|^(NO_MATCH)$|}, ':fa' );};
263 Check( $@ =~ m|insecure cwd| );
264 chdir($cwd_untainted);
266 print "# check preprocess\n";
268 ':' => {fa => 1, fb => 1},
269 ':fa:' => {faa => 1, fab => 1, fa_ord => 1},
270 ':fa:faa:' => {faa_ord => 1},
271 ':fa:fab:' => {faba => 1, fab_ord => 1},
272 ':fa:fab:faba:' => {faba_ord => 1},
273 ':fb:' => {fba => 1, fb_ord => 1},
274 ':fb:fba:' => {fba_ord => 1}
276 File::Find::find( {wanted => \&noop_wanted, untaint => 1, preprocess => \&my_preprocess}, ':' );
277 Check( scalar(keys %Expect) == 0 );
279 print "# check postprocess\n";
280 %Expect=(':' => 1, ':fa:' => 1, ':fa:faa:' => 1, ':fa:fab:' => 1, ':fa:fab:faba:' => 1, ':fb:' => 1,
282 File::Find::find( {wanted => \&noop_wanted, untaint => 1, postprocess => \&my_postprocess}, ':' );
283 Check( scalar(keys %Expect) == 0 );
285 # Verify that File::Find::find will call wanted even if the topdir of
286 # is a symlink to a directory, and it shouldn't follow the link
287 # unless follow is set, which it isn't in this case
288 %Expect = ('fsl' => 1);
290 File::Find::find( {wanted => \&wanted, untaint => 1},':fa:fsl' );
291 Check( scalar(keys %Expect) == 0 );
293 if ( $symlink_exists ) {
294 $FastFileTests_OK= 1;
295 %Expect=(':' => 1, 'fa_ord' => 1, 'fsl' => 1, 'fb_ord' => 1, 'fba' => 1,
296 'fba_ord' => 1, 'fab' => 1, 'fab_ord' => 1, 'faba' => 1, 'faa' => 1,
298 %Expect_Dir = (':' => 1, 'fa' => 1, 'faa' => 1, 'fab' => 1, 'faba' => 1,
299 'fb' => 1, 'fba' => 1);
300 File::Find::find( {wanted => \&wanted, follow_fast => 1, untaint => 1},':fa' );
301 Check( scalar(keys %Expect) == 0 );
303 %Expect=(':fa' => 1, ':fa:fa_ord' => 1, ':fa:fsl' => 1, ':fa:fsl:fb_ord' => 1,
304 ':fa:fsl:fba' => 1, ':fa:fsl:fba:fba_ord' => 1, ':fa:fab' => 1,
305 ':fa:fab:fab_ord' => 1, ':fa:fab:faba' => 1, ':fa:fab:faba:faba_ord' => 1,
306 ':fa:faa' => 1, ':fa:faa:faa_ord' => 1);
307 %Expect_Dir = (':fa' => 1, ':fa:faa' => 1, ':fa:fab' => 1, ':fa:fab:faba' => 1,
308 ':fb' => 1, ':fb:fba' => 1);
309 File::Find::find( {wanted => \&wanted, follow_fast => 1, no_chdir => 1, untaint => 1 },':fa' );
310 Check( scalar(keys %Expect) == 0 );
312 %Expect=(':fa' => 1, ':fa:fa_ord' => 1, ':fa:fsl' => 1, ':fa:fsl:fb_ord' => 1,
313 ':fa:fsl:fba' => 1, ':fa:fsl:fba:fba_ord' => 1, ':fa:fab' => 1,
314 ':fa:fab:fab_ord' => 1, ':fa:fab:faba' => 1, ':fa:fab:faba:faba_ord' => 1,
315 ':fa:faa' => 1, ':fa:faa:faa_ord' => 1);
316 %Expect_Dir = (':fa' => 1, ':fa:faa' => 1, ':fa:fab' => 1, ':fa:fab:faba' => 1,
317 ':fb' => 1, ':fb:fba' => 1);
318 File::Find::finddepth( {wanted => \&dn_wanted, follow_fast => 1, untaint => 1 },':fa' );
319 Check( scalar(keys %Expect) == 0 );
321 %Expect=(':fa' => 1, ':fa:fa_ord' => 1, ':fa:fsl' => 1, ':fa:fsl:fb_ord' => 1,
322 ':fa:fsl:fba' => 1, ':fa:fsl:fba:fba_ord' => 1, ':fa:fab' => 1,
323 ':fa:fab:fab_ord' => 1, ':fa:fab:faba' => 1, ':fa:fab:faba:faba_ord' => 1,
324 ':fa:faa' => 1, ':fa:faa:faa_ord' => 1);
325 %Expect_Dir = (':fa' => 1, ':fa:faa' => 1, ':fa:fab' => 1, ':fa:fab:faba' => 1,
326 ':fb' => 1, ':fb:fba' => 1);
327 File::Find::finddepth( {wanted => \&d_wanted, follow_fast => 1, no_chdir => 1, untaint => 1 },':fa' );
328 Check( scalar(keys %Expect) == 0 );
330 # tests below added by Thomas Wegner, 17-05-2001
332 print "# check dangling symbolic links\n";
333 MkDir( 'dangling_dir',0770 );
334 CheckDie( symlink('dangling_dir','dangling_dir_sl') );
335 rmdir 'dangling_dir';
336 touch('dangling_file');
337 CheckDie( symlink('dangling_file',':fa:dangling_file_sl') );
338 unlink 'dangling_file';
340 %Expect=(':' => 1, 'fa_ord' => 1, 'fsl' => 1, 'fb_ord' => 1, 'fba' => 1,
341 'fba_ord' => 1, 'fab' => 1, 'fab_ord' => 1, 'faba' => 1, 'faba_ord' => 1,
342 'faa' => 1, 'faa_ord' => 1);
343 %Expect_Dir = (':' => 1, 'fa' => 1, 'faa' => 1, 'fab' => 1, 'faba' => 1,
344 'fb' => 1, 'fba' => 1);
346 File::Find::find( {wanted => \&d_wanted, follow => 1, untaint => 1 }, 'dangling_dir_sl', ':fa' );
347 Check( $warn_msg =~ m|dangling_dir_sl is a dangling symbolic link| );
348 unlink ':fa:dangling_file_sl', 'dangling_dir_sl';
350 print "# check recursion\n";
351 CheckDie( symlink(':fa:faa',':fa:faa:faa_sl') );
353 eval {File::Find::find( {wanted => \&simple_wanted, follow => 1, no_chdir => 1, untaint => 1 },':fa' ); };
355 Check( $@ =~ m|:for_find:fa:faa:faa_sl is a recursive symbolic link| );
356 unlink ':fa:faa:faa_sl';
358 print "# check follow_skip (file)\n";
359 CheckDie( symlink(':fa:fa_ord',':fa:fa_ord_sl') ); # symlink to a file
361 eval {File::Find::finddepth( {wanted => \&simple_wanted, follow => 1,follow_skip => 0,
362 no_chdir => 1, untaint => 1 },':fa' );};
364 Check( $@ =~ m|:for_find:fa:fa_ord encountered a second time| );
366 %Expect=(':fa' => 1, ':fa:fa_ord' => 1, ':fa:fsl' => 1, ':fa:fsl:fb_ord' => 1,
367 ':fa:fsl:fba' => 1, ':fa:fsl:fba:fba_ord' => 1, ':fa:fab' => 1,
368 ':fa:fab:fab_ord' => 1, ':fa:fab:faba' => 1, ':fa:fab:faba:faba_ord' => 1,
369 ':fa:faa' => 1, ':fa:faa:faa_ord' => 1);
370 %Expect_Dir = (':fa' => 1, ':fa:faa' => 1, ':fa:fab' => 1, ':fa:fab:faba' => 1,
371 ':fb' => 1, ':fb:fba' => 1);
372 File::Find::finddepth( {wanted => \&wanted, follow => 1, follow_skip => 1, no_chdir => 1,
373 untaint => 1 },':fa' );
374 Check( scalar(keys %Expect) == 0 );
375 unlink ':fa:fa_ord_sl';
377 print "# check follow_skip (directory)\n";
378 CheckDie( symlink(':fa:faa',':fa:faa_sl') ); # symlink to a directory
380 eval {File::Find::find( {wanted => \&simple_wanted, follow => 1, follow_skip => 0,
381 no_chdir => 1, untaint => 1 },':fa' );};
383 Check( $@ =~ m|:for_find:fa:faa: encountered a second time| );
386 eval {File::Find::find( {wanted => \&simple_wanted, follow => 1, follow_skip => 1,
387 no_chdir => 1, untaint => 1 },':fa' );};
389 Check( $@ =~ m|:for_find:fa:faa: encountered a second time| );
391 %Expect=(':fa' => 1, ':fa:fa_ord' => 1, ':fa:fsl' => 1, ':fa:fsl:fb_ord' => 1,
392 ':fa:fsl:fba' => 1, ':fa:fsl:fba:fba_ord' => 1, ':fa:fab' => 1,
393 ':fa:fab:fab_ord' => 1, ':fa:fab:faba' => 1, ':fa:fab:faba:faba_ord' => 1,
394 ':fa:faa' => 1, ':fa:faa:faa_ord' => 1);
395 %Expect_Dir = (':fa' => 1, ':fa:faa' => 1, ':fa:fab' => 1, ':fa:fab:faba' => 1,
396 ':fb' => 1, ':fb:fba' => 1);
397 File::Find::find( {wanted => \&wanted, follow => 1, follow_skip => 2, no_chdir => 1,
398 untaint => 1},':fa' );
399 Check( scalar(keys %Expect) == 0 );
402 print "# check untainting (follow)\n";
403 # don't untaint at all
405 eval {File::Find::find( {wanted => \&simple_wanted, follow => 1},':fa' );};
407 Check( $@ =~ m|Insecure dependency| );
408 chdir($cwd_untainted);
411 eval {File::Find::find( {wanted => \&simple_wanted, follow => 1, untaint => 1,
412 untaint_pattern => qr|^(NO_MATCH)$|},':fa' );};
414 Check( $@ =~ m|is still tainted| );
415 chdir($cwd_untainted);
417 print "# check untaint_skip (follow)\n";
419 eval {File::Find::find( {wanted => \&simple_wanted, untaint => 1, untaint_skip => 1,
420 untaint_pattern => qr|^(NO_MATCH)$|}, ':fa' );};
422 Check( $@ =~ m|insecure cwd| );
423 chdir($cwd_untainted);
429 MkDir( 'for_find',0770 );
430 CheckDie(chdir(for_find));
432 $cwd = cwd(); # save cwd
433 ( $cwd_untainted ) = $cwd =~ m|^(.+)$|; # untaint it
438 MkDir( 'fb/fba',0770 );
439 touch('fb/fba/fba_ord');
440 CheckDie( symlink('../fb','fa/fsl') ) if $symlink_exists;
443 MkDir( 'fa/faa',0770 );
444 touch('fa/faa/faa_ord');
445 MkDir( 'fa/fab',0770 );
446 touch('fa/fab/fab_ord');
447 MkDir( 'fa/fab/faba',0770 );
448 touch('fa/fab/faba/faba_ord');
450 %Expect = ('.' => 1, 'fsl' => 1, 'fa_ord' => 1, 'fab' => 1, 'fab_ord' => 1,
451 'faba' => 1, 'faa' => 1, 'faa_ord' => 1);
452 delete $Expect{'fsl'} unless $symlink_exists;
453 %Expect_Dir = ('fa' => 1, 'faa' => 1, 'fab' => 1, 'faba' => 1,
454 'fb' => 1, 'fba' => 1);
455 delete @Expect_Dir{'fb','fba'} unless $symlink_exists;
456 File::Find::find( {wanted => \&wanted, untaint => 1, untaint_pattern => qr|^(.+)$|},'fa' );
457 Check( scalar(keys %Expect) == 0 );
459 %Expect=('fa' => 1, 'fa/fsl' => 1, 'fa/fa_ord' => 1, 'fa/fab' => 1,
460 'fa/fab/fab_ord' => 1, 'fa/fab/faba' => 1,
461 'fa/fab/faba/faba_ord' => 1, 'fa/faa' => 1, 'fa/faa/faa_ord' => 1);
462 delete $Expect{'fa/fsl'} unless $symlink_exists;
463 %Expect_Dir = ('fa' => 1, 'fa/faa' => 1, '/fa/fab' => 1, 'fa/fab/faba' => 1,
464 'fb' => 1, 'fb/fba' => 1);
465 delete @Expect_Dir{'fb','fb/fba'} unless $symlink_exists;
466 File::Find::find( {wanted => \&wanted, no_chdir => 1, untaint => 1, untaint_pattern => qr|^(.+)$|},'fa' );
467 Check( scalar(keys %Expect) == 0 );
469 %Expect=('.' => 1, './fa' => 1, './fa/fsl' => 1, './fa/fa_ord' => 1, './fa/fab' => 1,
470 './fa/fab/fab_ord' => 1, './fa/fab/faba' => 1,
471 './fa/fab/faba/faba_ord' => 1, './fa/faa' => 1, './fa/faa/faa_ord' => 1,
472 './fb' => 1, './fb/fba' => 1, './fb/fba/fba_ord' => 1, './fb/fb_ord' => 1);
473 delete $Expect{'./fa/fsl'} unless $symlink_exists;
474 %Expect_Dir = ('./fa' => 1, './fa/faa' => 1, '/fa/fab' => 1, './fa/fab/faba' => 1,
475 './fb' => 1, './fb/fba' => 1);
476 delete @Expect_Dir{'./fb','./fb/fba'} unless $symlink_exists;
477 File::Find::finddepth( {wanted => \&dn_wanted , untaint => 1, untaint_pattern => qr|^(.+)$|},'.' );
478 Check( scalar(keys %Expect) == 0 );
480 %Expect=('.' => 1, './fa' => 1, './fa/fsl' => 1, './fa/fa_ord' => 1, './fa/fab' => 1,
481 './fa/fab/fab_ord' => 1, './fa/fab/faba' => 1,
482 './fa/fab/faba/faba_ord' => 1, './fa/faa' => 1, './fa/faa/faa_ord' => 1,
483 './fb' => 1, './fb/fba' => 1, './fb/fba/fba_ord' => 1, './fb/fb_ord' => 1);
484 delete $Expect{'./fa/fsl'} unless $symlink_exists;
485 %Expect_Dir = ('./fa' => 1, './fa/faa' => 1, '/fa/fab' => 1, './fa/fab/faba' => 1,
486 './fb' => 1, './fb/fba' => 1);
487 delete @Expect_Dir{'./fb','./fb/fba'} unless $symlink_exists;
488 File::Find::finddepth( {wanted => \&d_wanted, no_chdir => 1, untaint => 1, untaint_pattern => qr|^(.+)$| },'.' );
489 Check( scalar(keys %Expect) == 0 );
491 # untaint, preprocess and postprocess tests below added by Thomas Wegner, 17-05-2001
493 print "# check untainting (no follow)\n";
494 # don't untaint at all
496 eval {File::Find::find( {wanted => \&simple_wanted},'fa' );};
498 Check( $@ =~ m|Insecure dependency| );
499 chdir($cwd_untainted);
502 eval {File::Find::find( {wanted => \&simple_wanted, untaint => 1,
503 untaint_pattern => qr|^(NO_MATCH)$|},'fa' );};
505 Check( $@ =~ m|is still tainted| );
506 chdir($cwd_untainted);
508 print "# check untaint_skip (no follow)\n";
510 eval {File::Find::find( {wanted => \&simple_wanted, untaint => 1, untaint_skip => 1,
511 untaint_pattern => qr|^(NO_MATCH)$|}, 'fa' );};
513 Check( $@ =~ m|insecure cwd| );
514 chdir($cwd_untainted);
516 print "# check preprocess\n";
518 '.' => {fa => 1, fb => 1},
519 './fa' => {faa => 1, fab => 1, fa_ord => 1},
520 './fa/faa' => {faa_ord => 1},
521 './fa/fab' => {faba => 1, fab_ord => 1},
522 './fa/fab/faba' => {faba_ord => 1},
523 './fb' => {fba => 1, fb_ord => 1},
524 './fb/fba' => {fba_ord => 1}
527 File::Find::find( {wanted => \&noop_wanted, preprocess => \&my_preprocess, untaint => 1,
528 untaint_pattern => qr|^(.+)$|}, '.' );
529 Check( scalar(keys %Expect) == 0 );
531 print "# check postprocess\n";
532 %Expect=('.' => 1, './fa' => 1, './fa/faa' => 1, './fa/fab' => 1, './fa/fab/faba' => 1, './fb' => 1,
534 File::Find::find( {wanted => \&noop_wanted, postprocess => \&my_postprocess, untaint => 1,
535 untaint_pattern => qr|^(.+)$|}, '.' );
536 Check( scalar(keys %Expect) == 0 );
538 # Verify that File::Find::find will call wanted even if the topdir of
539 # is a symlink to a directory, and it shouldn't follow the link
540 # unless follow is set, which it isn't in this case
541 %Expect = ('fsl' => 1);
543 File::Find::find( {wanted => \&wanted, untaint => 1},'fa/fsl' );
544 Check( scalar(keys %Expect) == 0 );
546 if ( $symlink_exists ) {
547 $FastFileTests_OK= 1;
548 %Expect=('.' => 1, 'fa_ord' => 1, 'fsl' => 1, 'fb_ord' => 1, 'fba' => 1,
549 'fba_ord' => 1, 'fab' => 1, 'fab_ord' => 1, 'faba' => 1, 'faa' => 1,
551 %Expect_Dir = ('fa' => 1, 'fa/faa' => 1, '/fa/fab' => 1, 'fa/fab/faba' => 1,
552 'fb' => 1, 'fb/fba' => 1);
553 File::Find::find( {wanted => \&wanted, follow_fast => 1, untaint => 1, untaint_pattern => qr|^(.+)$|},'fa' );
554 Check( scalar(keys %Expect) == 0 );
556 %Expect=('fa' => 1, 'fa/fa_ord' => 1, 'fa/fsl' => 1, 'fa/fsl/fb_ord' => 1,
557 'fa/fsl/fba' => 1, 'fa/fsl/fba/fba_ord' => 1, 'fa/fab' => 1,
558 'fa/fab/fab_ord' => 1, 'fa/fab/faba' => 1, 'fa/fab/faba/faba_ord' => 1,
559 'fa/faa' => 1, 'fa/faa/faa_ord' => 1);
560 %Expect_Dir = ('fa' => 1, 'fa/faa' => 1, '/fa/fab' => 1, 'fa/fab/faba' => 1,
561 'fb' => 1, 'fb/fba' => 1);
562 File::Find::find( {wanted => \&wanted, follow_fast => 1, no_chdir => 1, untaint => 1,
563 untaint_pattern => qr|^(.+)$|},'fa' );
564 Check( scalar(keys %Expect) == 0 );
566 %Expect=('fa' => 1, 'fa/fa_ord' => 1, 'fa/fsl' => 1, 'fa/fsl/fb_ord' => 1,
567 'fa/fsl/fba' => 1, 'fa/fsl/fba/fba_ord' => 1, 'fa/fab' => 1,
568 'fa/fab/fab_ord' => 1, 'fa/fab/faba' => 1, 'fa/fab/faba/faba_ord' => 1,
569 'fa/faa' => 1, 'fa/faa/faa_ord' => 1);
570 %Expect_Dir = ('fa' => 1, 'fa/faa' => 1, '/fa/fab' => 1, 'fa/fab/faba' => 1,
571 'fb' => 1, 'fb/fba' => 1);
572 File::Find::finddepth( {wanted => \&dn_wanted, follow_fast => 1, untaint => 1,
573 untaint_pattern => qr|^(.+)$|},'fa' );
574 Check( scalar(keys %Expect) == 0 );
576 %Expect=('fa' => 1, 'fa/fa_ord' => 1, 'fa/fsl' => 1, 'fa/fsl/fb_ord' => 1,
577 'fa/fsl/fba' => 1, 'fa/fsl/fba/fba_ord' => 1, 'fa/fab' => 1,
578 'fa/fab/fab_ord' => 1, 'fa/fab/faba' => 1, 'fa/fab/faba/faba_ord' => 1,
579 'fa/faa' => 1, 'fa/faa/faa_ord' => 1);
580 %Expect_Dir = ('fa' => 1, 'fa/faa' => 1, '/fa/fab' => 1, 'fa/fab/faba' => 1,
581 'fb' => 1, 'fb/fba' => 1);
582 File::Find::finddepth( {wanted => \&d_wanted, follow_fast => 1, no_chdir => 1,
583 untaint => 1, untaint_pattern => qr|^(.+)$|},'fa' );
584 Check( scalar(keys %Expect) == 0 );
586 # tests below added by Thomas Wegner, 17-05-2001
588 print "# check dangling symbolic links\n";
589 MkDir( 'dangling_dir',0770 );
590 CheckDie( symlink('dangling_dir','dangling_dir_sl') );
591 rmdir 'dangling_dir';
592 touch('dangling_file');
593 CheckDie( symlink('../dangling_file','fa/dangling_file_sl') );
594 unlink 'dangling_file';
596 %Expect=('.' => 1, 'fa_ord' => 1, 'fsl' => 1, 'fb_ord' => 1, 'fba' => 1,
597 'fba_ord' => 1, 'fab' => 1, 'fab_ord' => 1, 'faba' => 1, 'faba_ord' => 1,
598 'faa' => 1, 'faa_ord' => 1);
599 %Expect_Dir = ('fa' => 1, 'fa/faa' => 1, 'fa/fab' => 1, 'fa/fab/faba' => 1,
600 'fb' => 1, 'fb/fba' => 1);
602 File::Find::find( {wanted => \&d_wanted, follow => 1, untaint => 1,
603 untaint_pattern => qr|^(.+)$|}, 'dangling_dir_sl', 'fa' );
604 Check( $warn_msg =~ m|dangling_dir_sl is a dangling symbolic link| );
605 unlink 'fa/dangling_file_sl', 'dangling_dir_sl';
607 print "# check recursion\n";
608 CheckDie( symlink('../faa','fa/faa/faa_sl') );
610 eval {File::Find::find( {wanted => \&simple_wanted, follow => 1, no_chdir => 1,
611 untaint => 1, untaint_pattern => qr|^(.+)$|},'fa' ); };
613 Check( $@ =~ m|for_find/fa/faa/faa_sl is a recursive symbolic link| );
614 unlink 'fa/faa/faa_sl';
616 print "# check follow_skip (file)\n";
617 CheckDie( symlink('./fa_ord','fa/fa_ord_sl') ); # symlink to a file
619 eval {File::Find::finddepth( {wanted => \&simple_wanted, follow => 1, follow_skip => 0, no_chdir => 1,
620 untaint => 1, untaint_pattern => qr|^(.+)$|},'fa' );};
622 Check( $@ =~ m|for_find/fa/fa_ord encountered a second time| );
624 %Expect=('fa' => 1, 'fa/fa_ord' => 1, 'fa/fsl' => 1, 'fa/fsl/fb_ord' => 1,
625 'fa/fsl/fba' => 1, 'fa/fsl/fba/fba_ord' => 1, 'fa/fab' => 1,
626 'fa/fab/fab_ord' => 1, 'fa/fab/faba' => 1, 'fa/fab/faba/faba_ord' => 1,
627 'fa/faa' => 1, 'fa/faa/faa_ord' => 1);
628 %Expect_Dir = ('fa' => 1, 'fa/faa' => 1, '/fa/fab' => 1, 'fa/fab/faba' => 1,
629 'fb' => 1, 'fb/fba' => 1);
630 File::Find::finddepth( {wanted => \&wanted, follow => 1, follow_skip => 1, no_chdir => 1,
631 untaint => 1, untaint_pattern => qr|^(.+)$|},'fa' );
632 Check( scalar(keys %Expect) == 0 );
633 unlink 'fa/fa_ord_sl';
635 print "# check follow_skip (directory)\n";
636 CheckDie( symlink('./faa','fa/faa_sl') ); # symlink to a directory
638 eval {File::Find::find( {wanted => \&simple_wanted, follow => 1, follow_skip => 0, no_chdir => 1,
639 untaint => 1, untaint_pattern => qr|^(.+)$|},'fa' );};
641 Check( $@ =~ m|for_find/fa/faa encountered a second time| );
644 eval {File::Find::find( {wanted => \&simple_wanted, follow => 1, follow_skip => 1, no_chdir => 1,
645 untaint => 1, untaint_pattern => qr|^(.+)$|},'fa' );};
647 Check( $@ =~ m|for_find/fa/faa encountered a second time| );
649 %Expect=('fa' => 1, 'fa/fa_ord' => 1, 'fa/fsl' => 1, 'fa/fsl/fb_ord' => 1,
650 'fa/fsl/fba' => 1, 'fa/fsl/fba/fba_ord' => 1, 'fa/fab' => 1,
651 'fa/fab/fab_ord' => 1, 'fa/fab/faba' => 1, 'fa/fab/faba/faba_ord' => 1,
652 'fa/faa' => 1, 'fa/faa/faa_ord' => 1);
653 %Expect_Dir = ('fa' => 1, 'fa/faa' => 1, '/fa/fab' => 1, 'fa/fab/faba' => 1,
654 'fb' => 1, 'fb/fba' => 1);
655 File::Find::find( {wanted => \&wanted, follow => 1, follow_skip => 2, no_chdir => 1,
656 untaint => 1, untaint_pattern => qr|^(.+)$|},'fa' );
657 Check( scalar(keys %Expect) == 0 );
660 print "# check untainting (follow)\n";
661 # don't untaint at all
663 eval {File::Find::find( {wanted => \&simple_wanted, follow => 1},'fa' );};
665 Check( $@ =~ m|Insecure dependency| );
666 chdir($cwd_untainted);
669 eval {File::Find::find( {wanted => \&simple_wanted, follow => 1, untaint => 1,
670 untaint_pattern => qr|^(NO_MATCH)$|},'fa' );};
672 Check( $@ =~ m|is still tainted| );
673 chdir($cwd_untainted);
675 print "# check untaint_skip (follow)\n";
677 eval {File::Find::find( {wanted => \&simple_wanted, untaint => 1, untaint_skip => 1,
678 untaint_pattern => qr|^(NO_MATCH)$|}, 'fa' );};
680 Check( $@ =~ m|insecure cwd| );
681 chdir($cwd_untainted);
686 print "# of cases: $case\n";