Commit | Line | Data |
7e47e6ff |
1 | #!./perl -T |
81793b90 |
2 | |
3 | |
4 | my %Expect; |
5 | my $symlink_exists = eval { symlink("",""); 1 }; |
7e47e6ff |
6 | my $warn_msg; |
7 | my $cwd; |
8 | my $cwd_untainted; |
1a3850a5 |
9 | |
10 | BEGIN { |
11 | chdir 't' if -d 't'; |
7e47e6ff |
12 | @INC = '../lib'; |
13 | |
14 | for (keys %ENV) { # untaint ENV |
15 | ($ENV{$_}) = keys %{{ map {$_ => 1} $ENV{$_} }}; |
16 | } |
17 | |
18 | $SIG{'__WARN__'} = sub { $warn_msg = $_[0]; warn "# Warn: $_[0]"; } |
1a3850a5 |
19 | } |
20 | |
7e47e6ff |
21 | if ( $symlink_exists ) { print "1..184\n"; } |
22 | else { print "1..75\n"; } |
1a3850a5 |
23 | |
24 | use File::Find; |
7e47e6ff |
25 | use Cwd; |
1a3850a5 |
26 | |
24e8cdb8 |
27 | # Remove insecure directories from PATH |
28 | my @path; |
29 | my $sep = ($^O eq 'MSWin32') ? ';' : ':'; |
30 | foreach my $dir (split(/$sep/,$ENV{'PATH'})) |
31 | { |
32 | push(@path,$dir) unless -w $dir; |
33 | } |
34 | $ENV{'PATH'} = join($sep,@path); |
35 | |
c80f55d1 |
36 | cleanup(); |
37 | |
7e47e6ff |
38 | if ($^O eq 'MacOS') { |
24e8cdb8 |
39 | find({wanted => sub { print "ok 1\n" if $_ eq 'filefind.t'; }, untaint => 1}, ':'); |
7e47e6ff |
40 | finddepth({wanted => sub { print "ok 2\n" if $_ eq 'filefind.t'; }, untaint => 1}, ':'); |
41 | } else { |
42 | find({wanted => sub { print "ok 1\n" if $_ eq 'filefind.t'; }, untaint => 1, |
43 | untaint_pattern => qr|^(.+)$|}, '.'); |
24e8cdb8 |
44 | finddepth({wanted => sub { print "ok 2\n" if $_ eq 'filefind.t'; }, |
7e47e6ff |
45 | untaint => 1, untaint_pattern => qr|^(.+)$|}, '.'); |
46 | } |
81793b90 |
47 | |
81793b90 |
48 | my $case = 2; |
5eb85357 |
49 | my $FastFileTests_OK = 0; |
81793b90 |
50 | |
c80f55d1 |
51 | sub cleanup { |
7e47e6ff |
52 | if ($^O eq 'MacOS') { |
53 | if (-d ':for_find') { |
54 | chdir(':for_find'); |
55 | } |
56 | if (-d ':fa') { |
57 | unlink ':fa:fa_ord',':fa:fsl',':fa:faa:faa_ord', |
58 | ':fa:fab:fab_ord',':fa:fab:faba:faba_ord', |
59 | ':fb:fb_ord',':fb:fba:fba_ord'; |
60 | rmdir ':fa:faa'; |
61 | rmdir ':fa:fab:faba'; |
62 | rmdir ':fa:fab'; |
63 | rmdir ':fa'; |
64 | rmdir ':fb:fba'; |
65 | rmdir ':fb'; |
66 | chdir '::'; |
67 | rmdir ':for_find'; |
68 | } |
69 | } else { |
70 | if (-d 'for_find') { |
71 | chdir('for_find'); |
72 | } |
73 | if (-d 'fa') { |
74 | unlink 'fa/fa_ord','fa/fsl','fa/faa/faa_ord', |
75 | 'fa/fab/fab_ord','fa/fab/faba/faba_ord', |
76 | 'fb/fb_ord','fb/fba/fba_ord'; |
77 | rmdir 'fa/faa'; |
78 | rmdir 'fa/fab/faba'; |
79 | rmdir 'fa/fab'; |
80 | rmdir 'fa'; |
81 | rmdir 'fb/fba'; |
82 | rmdir 'fb'; |
83 | chdir '..'; |
84 | rmdir 'for_find'; |
85 | } |
c80f55d1 |
86 | } |
87 | } |
88 | |
81793b90 |
89 | END { |
c80f55d1 |
90 | cleanup(); |
81793b90 |
91 | } |
92 | |
93 | sub Check($) { |
94 | $case++; |
95 | if ($_[0]) { print "ok $case\n"; } |
96 | else { print "not ok $case\n"; } |
97 | } |
98 | |
99 | sub CheckDie($) { |
100 | $case++; |
101 | if ($_[0]) { print "ok $case\n"; } |
102 | else { print "not ok $case\n $!\n"; exit 0; } |
103 | } |
104 | |
105 | sub touch { |
106 | CheckDie( open(my $T,'>',$_[0]) ); |
107 | } |
108 | |
109 | sub MkDir($$) { |
110 | CheckDie( mkdir($_[0],$_[1]) ); |
111 | } |
112 | |
113 | sub wanted { |
24e8cdb8 |
114 | print "# '$_' => 1\n"; |
11611c0f |
115 | s#\.$## if ($^O eq 'VMS' && $_ ne '.'); |
81793b90 |
116 | Check( $Expect{$_} ); |
5eb85357 |
117 | if ( $FastFileTests_OK ) { |
24e8cdb8 |
118 | delete $Expect{$_} |
5eb85357 |
119 | unless ( $Expect_Dir{$_} && ! -d _ ); |
120 | } else { |
24e8cdb8 |
121 | delete $Expect{$_} |
5eb85357 |
122 | unless ( $Expect_Dir{$_} && ! -d $_ ); |
123 | } |
10fbe481 |
124 | $File::Find::prune=1 if $_ eq 'faba'; |
7e47e6ff |
125 | |
81793b90 |
126 | } |
127 | |
57907763 |
128 | sub dn_wanted { |
129 | my $n = $File::Find::name; |
11611c0f |
130 | $n =~ s#\.$## if ($^O eq 'VMS' && $n ne '.'); |
57907763 |
131 | print "# '$n' => 1\n"; |
132 | my $i = rindex($n,'/'); |
133 | my $OK = exists($Expect{$n}); |
7e47e6ff |
134 | unless ($^O eq 'MacOS') { |
135 | if ( $OK ) { |
24e8cdb8 |
136 | $OK= exists($Expect{substr($n,0,$i)}) if $i >= 0; |
7e47e6ff |
137 | } |
57907763 |
138 | } |
139 | Check($OK); |
140 | delete $Expect{$n}; |
141 | } |
142 | |
143 | sub d_wanted { |
144 | print "# '$_' => 1\n"; |
11611c0f |
145 | s#\.$## if ($^O eq 'VMS' && $_ ne '.'); |
57907763 |
146 | my $i = rindex($_,'/'); |
147 | my $OK = exists($Expect{$_}); |
7e47e6ff |
148 | unless ($^O eq 'MacOS') { |
149 | if ( $OK ) { |
150 | $OK= exists($Expect{substr($_,0,$i)}) if $i >= 0; |
151 | } |
57907763 |
152 | } |
153 | Check($OK); |
154 | delete $Expect{$_}; |
155 | } |
156 | |
7e47e6ff |
157 | sub simple_wanted { |
158 | print "# \$File::Find::dir => '$File::Find::dir'\n"; |
159 | print "# \$_ => '$_'\n"; |
160 | } |
161 | |
162 | sub noop_wanted {} |
78eac027 |
163 | |
7e47e6ff |
164 | sub my_preprocess { |
165 | @files = @_; |
166 | print "# --PREPROCESS--\n"; |
167 | print "# \$File::Find::dir => '$File::Find::dir' \n"; |
168 | foreach $file (@files) { |
169 | print "# $file \n"; |
170 | delete $Expect{$File::Find::dir}->{$file}; |
171 | } |
172 | print "# --END PREPROCESS--\n"; |
173 | Check(scalar(keys %{$Expect{$File::Find::dir}}) == 0); |
174 | if (scalar(keys %{$Expect{$File::Find::dir}}) == 0) { |
175 | delete $Expect{$File::Find::dir} |
176 | } |
177 | return @files; |
178 | } |
179 | |
180 | sub my_postprocess { |
181 | print "# POSTPROCESS: \$File::Find::dir => '$File::Find::dir' \n"; |
182 | delete $Expect{$File::Find::dir}; |
183 | } |
184 | |
185 | |
186 | if ($^O eq 'MacOS') { |
187 | |
188 | MkDir( 'for_find',0770 ); |
189 | CheckDie(chdir(for_find)); |
190 | |
191 | $cwd = cwd(); # save cwd |
192 | ( $cwd_untainted ) = $cwd =~ m|^(.+)$|; # untaint it |
193 | |
194 | MkDir( 'fa',0770 ); |
195 | MkDir( 'fb',0770 ); |
196 | touch(':fb:fb_ord'); |
197 | MkDir( ':fb:fba',0770 ); |
198 | touch(':fb:fba:fba_ord'); |
199 | CheckDie( symlink(':fb',':fa:fsl') ) if $symlink_exists; |
200 | touch(':fa:fa_ord'); |
201 | |
202 | MkDir( ':fa:faa',0770 ); |
203 | touch(':fa:faa:faa_ord'); |
204 | MkDir( ':fa:fab',0770 ); |
205 | touch(':fa:fab:fab_ord'); |
206 | MkDir( ':fa:fab:faba',0770 ); |
207 | touch(':fa:fab:faba:faba_ord'); |
208 | |
209 | %Expect = (':' => 1, 'fsl' => 1, 'fa_ord' => 1, 'fab' => 1, 'fab_ord' => 1, |
210 | 'faba' => 1, 'faa' => 1, 'faa_ord' => 1); |
211 | delete $Expect{'fsl'} unless $symlink_exists; |
24e8cdb8 |
212 | %Expect_Dir = (':' => 1, 'fa' => 1, 'faa' => 1, 'fab' => 1, 'faba' => 1, |
7e47e6ff |
213 | 'fb' => 1, 'fba' => 1); |
214 | delete @Expect_Dir{'fb','fba'} unless $symlink_exists; |
24e8cdb8 |
215 | File::Find::find( {wanted => \&wanted, untaint => 1},':fa' ); |
7e47e6ff |
216 | Check( scalar(keys %Expect) == 0 ); |
217 | |
218 | %Expect=(':fa' => 1, ':fa:fsl' => 1, ':fa:fa_ord' => 1, ':fa:fab' => 1, |
219 | ':fa:fab:fab_ord' => 1, ':fa:fab:faba' => 1, |
220 | ':fa:fab:faba:faba_ord' => 1, ':fa:faa' => 1, ':fa:faa:faa_ord' => 1); |
221 | delete $Expect{':fa:fsl'} unless $symlink_exists; |
24e8cdb8 |
222 | %Expect_Dir = (':fa' => 1, ':fa:faa' => 1, ':fa:fab' => 1, ':fa:fab:faba' => 1, |
7e47e6ff |
223 | ':fb' => 1, ':fb:fba' => 1); |
224 | delete @Expect_Dir{':fb',':fb:fba'} unless $symlink_exists; |
225 | File::Find::find( {wanted => \&wanted, no_chdir => 1, untaint => 1},':fa' ); |
226 | Check( scalar(keys %Expect) == 0 ); |
227 | |
228 | %Expect=(':' => 1, ':fa' => 1, ':fa:fsl' => 1, ':fa:fa_ord' => 1, ':fa:fab' => 1, |
229 | ':fa:fab:fab_ord' => 1, ':fa:fab:faba' => 1, |
230 | ':fa:fab:faba:faba_ord' => 1, ':fa:faa' => 1, ':fa:faa:faa_ord' => 1, |
231 | ':fb' => 1, ':fb:fba' => 1, ':fb:fba:fba_ord' => 1, ':fb:fb_ord' => 1); |
232 | delete $Expect{':fa:fsl'} unless $symlink_exists; |
24e8cdb8 |
233 | %Expect_Dir = (':' => 1, ':fa' => 1, ':fa:faa' => 1, ':fa:fab' => 1, ':fa:fab:faba' => 1, |
7e47e6ff |
234 | ':fb' => 1, ':fb:fba' => 1); |
235 | delete @Expect_Dir{':fb',':fb:fba'} unless $symlink_exists; |
236 | File::Find::finddepth( {wanted => \&dn_wanted, untaint => 1 },':' ); |
237 | Check( scalar(keys %Expect) == 0 ); |
238 | |
239 | %Expect=(':' => 1, ':fa' => 1, ':fa:fsl' => 1, ':fa:fa_ord' => 1, ':fa:fab' => 1, |
240 | ':fa:fab:fab_ord' => 1, ':fa:fab:faba' => 1, |
241 | ':fa:fab:faba:faba_ord' => 1, ':fa:faa' => 1, ':fa:faa:faa_ord' => 1, |
242 | ':fb' => 1, ':fb:fba' => 1, ':fb:fba:fba_ord' => 1, ':fb:fb_ord' => 1); |
243 | delete $Expect{':fa:fsl'} unless $symlink_exists; |
24e8cdb8 |
244 | %Expect_Dir = (':' => 1, ':fa' => 1, ':fa:faa' => 1, ':fa:fab' => 1, ':fa:fab:faba' => 1, |
7e47e6ff |
245 | ':fb' => 1, ':fb:fba' => 1); |
246 | delete @Expect_Dir{':fb',':fb:fba'} unless $symlink_exists; |
247 | File::Find::finddepth( {wanted => \&d_wanted, no_chdir => 1, untaint => 1 },':' ); |
248 | Check( scalar(keys %Expect) == 0 ); |
249 | |
250 | # untaint, preprocess and postprocess tests below added by Thomas Wegner, 17-05-2001 |
251 | |
252 | print "# check untainting (no follow)\n"; |
253 | # don't untaint at all |
254 | undef $@; |
255 | eval {File::Find::find( {wanted => \&simple_wanted},':fa' );}; |
256 | print "# Died: $@"; |
257 | Check( $@ =~ m|Insecure dependency| ); |
258 | chdir($cwd_untainted); |
259 | |
260 | undef $@; |
261 | eval {File::Find::find( {wanted => \&simple_wanted, untaint => 1, |
24e8cdb8 |
262 | untaint_pattern => qr|^(NO_MATCH)$|},':fa' );}; |
7e47e6ff |
263 | print "# Died: $@"; |
264 | Check( $@ =~ m|is still tainted| ); |
265 | chdir($cwd_untainted); |
266 | |
267 | print "# check untaint_skip (no follow)\n"; |
268 | undef $@; |
24e8cdb8 |
269 | eval {File::Find::find( {wanted => \&simple_wanted, untaint => 1, untaint_skip => 1, |
7e47e6ff |
270 | untaint_pattern => qr|^(NO_MATCH)$|}, ':fa' );}; |
271 | print "# Died: $@"; |
272 | Check( $@ =~ m|insecure cwd| ); |
273 | chdir($cwd_untainted); |
274 | |
275 | print "# check preprocess\n"; |
276 | %Expect=( |
24e8cdb8 |
277 | ':' => {fa => 1, fb => 1}, |
7e47e6ff |
278 | ':fa:' => {faa => 1, fab => 1, fa_ord => 1}, |
279 | ':fa:faa:' => {faa_ord => 1}, |
280 | ':fa:fab:' => {faba => 1, fab_ord => 1}, |
24e8cdb8 |
281 | ':fa:fab:faba:' => {faba_ord => 1}, |
7e47e6ff |
282 | ':fb:' => {fba => 1, fb_ord => 1}, |
283 | ':fb:fba:' => {fba_ord => 1} |
284 | ); |
285 | File::Find::find( {wanted => \&noop_wanted, untaint => 1, preprocess => \&my_preprocess}, ':' ); |
286 | Check( scalar(keys %Expect) == 0 ); |
287 | |
288 | print "# check postprocess\n"; |
289 | %Expect=(':' => 1, ':fa:' => 1, ':fa:faa:' => 1, ':fa:fab:' => 1, ':fa:fab:faba:' => 1, ':fb:' => 1, |
290 | ':fb:fba:' => 1 ); |
291 | File::Find::find( {wanted => \&noop_wanted, untaint => 1, postprocess => \&my_postprocess}, ':' ); |
292 | Check( scalar(keys %Expect) == 0 ); |
293 | |
294 | # Verify that File::Find::find will call wanted even if the topdir of |
295 | # is a symlink to a directory, and it shouldn't follow the link |
296 | # unless follow is set, which it isn't in this case |
297 | %Expect = ('fsl' => 1); |
298 | %Expect_Dir = (); |
299 | File::Find::find( {wanted => \&wanted, untaint => 1},':fa:fsl' ); |
300 | Check( scalar(keys %Expect) == 0 ); |
301 | |
302 | if ( $symlink_exists ) { |
303 | $FastFileTests_OK= 1; |
304 | %Expect=(':' => 1, 'fa_ord' => 1, 'fsl' => 1, 'fb_ord' => 1, 'fba' => 1, |
305 | 'fba_ord' => 1, 'fab' => 1, 'fab_ord' => 1, 'faba' => 1, 'faa' => 1, |
306 | 'faa_ord' => 1); |
24e8cdb8 |
307 | %Expect_Dir = (':' => 1, 'fa' => 1, 'faa' => 1, 'fab' => 1, 'faba' => 1, |
308 | 'fb' => 1, 'fba' => 1); |
7e47e6ff |
309 | File::Find::find( {wanted => \&wanted, follow_fast => 1, untaint => 1},':fa' ); |
24e8cdb8 |
310 | Check( scalar(keys %Expect) == 0 ); |
7e47e6ff |
311 | |
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); |
24e8cdb8 |
316 | %Expect_Dir = (':fa' => 1, ':fa:faa' => 1, ':fa:fab' => 1, ':fa:fab:faba' => 1, |
317 | ':fb' => 1, ':fb:fba' => 1); |
7e47e6ff |
318 | File::Find::find( {wanted => \&wanted, follow_fast => 1, no_chdir => 1, untaint => 1 },':fa' ); |
319 | Check( scalar(keys %Expect) == 0 ); |
320 | |
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); |
24e8cdb8 |
325 | %Expect_Dir = (':fa' => 1, ':fa:faa' => 1, ':fa:fab' => 1, ':fa:fab:faba' => 1, |
7e47e6ff |
326 | ':fb' => 1, ':fb:fba' => 1); |
327 | File::Find::finddepth( {wanted => \&dn_wanted, follow_fast => 1, untaint => 1 },':fa' ); |
328 | Check( scalar(keys %Expect) == 0 ); |
329 | |
330 | %Expect=(':fa' => 1, ':fa:fa_ord' => 1, ':fa:fsl' => 1, ':fa:fsl:fb_ord' => 1, |
331 | ':fa:fsl:fba' => 1, ':fa:fsl:fba:fba_ord' => 1, ':fa:fab' => 1, |
332 | ':fa:fab:fab_ord' => 1, ':fa:fab:faba' => 1, ':fa:fab:faba:faba_ord' => 1, |
333 | ':fa:faa' => 1, ':fa:faa:faa_ord' => 1); |
24e8cdb8 |
334 | %Expect_Dir = (':fa' => 1, ':fa:faa' => 1, ':fa:fab' => 1, ':fa:fab:faba' => 1, |
7e47e6ff |
335 | ':fb' => 1, ':fb:fba' => 1); |
336 | File::Find::finddepth( {wanted => \&d_wanted, follow_fast => 1, no_chdir => 1, untaint => 1 },':fa' ); |
24e8cdb8 |
337 | Check( scalar(keys %Expect) == 0 ); |
7e47e6ff |
338 | |
339 | # tests below added by Thomas Wegner, 17-05-2001 |
340 | |
341 | print "# check dangling symbolic links\n"; |
342 | MkDir( 'dangling_dir',0770 ); |
343 | CheckDie( symlink('dangling_dir','dangling_dir_sl') ); |
344 | rmdir 'dangling_dir'; |
345 | touch('dangling_file'); |
346 | CheckDie( symlink('dangling_file',':fa:dangling_file_sl') ); |
347 | unlink 'dangling_file'; |
348 | |
349 | %Expect=(':' => 1, 'fa_ord' => 1, 'fsl' => 1, 'fb_ord' => 1, 'fba' => 1, |
350 | 'fba_ord' => 1, 'fab' => 1, 'fab_ord' => 1, 'faba' => 1, 'faba_ord' => 1, |
351 | 'faa' => 1, 'faa_ord' => 1); |
24e8cdb8 |
352 | %Expect_Dir = (':' => 1, 'fa' => 1, 'faa' => 1, 'fab' => 1, 'faba' => 1, |
7e47e6ff |
353 | 'fb' => 1, 'fba' => 1); |
354 | undef $warn_msg; |
355 | File::Find::find( {wanted => \&d_wanted, follow => 1, untaint => 1 }, 'dangling_dir_sl', ':fa' ); |
24e8cdb8 |
356 | Check( $warn_msg =~ m|dangling_dir_sl is a dangling symbolic link| ); |
7e47e6ff |
357 | unlink ':fa:dangling_file_sl', 'dangling_dir_sl'; |
358 | |
359 | print "# check recursion\n"; |
360 | CheckDie( symlink(':fa:faa',':fa:faa:faa_sl') ); |
361 | undef $@; |
362 | eval {File::Find::find( {wanted => \&simple_wanted, follow => 1, no_chdir => 1, untaint => 1 },':fa' ); }; |
363 | print "# Died: $@"; |
24e8cdb8 |
364 | Check( $@ =~ m|:for_find:fa:faa:faa_sl is a recursive symbolic link| ); |
365 | unlink ':fa:faa:faa_sl'; |
7e47e6ff |
366 | |
367 | print "# check follow_skip (file)\n"; |
368 | CheckDie( symlink(':fa:fa_ord',':fa:fa_ord_sl') ); # symlink to a file |
369 | undef $@; |
24e8cdb8 |
370 | eval {File::Find::finddepth( {wanted => \&simple_wanted, follow => 1,follow_skip => 0, |
7e47e6ff |
371 | no_chdir => 1, untaint => 1 },':fa' );}; |
372 | print "# Died: $@"; |
373 | Check( $@ =~ m|:for_find:fa:fa_ord encountered a second time| ); |
374 | |
375 | %Expect=(':fa' => 1, ':fa:fa_ord' => 1, ':fa:fsl' => 1, ':fa:fsl:fb_ord' => 1, |
376 | ':fa:fsl:fba' => 1, ':fa:fsl:fba:fba_ord' => 1, ':fa:fab' => 1, |
377 | ':fa:fab:fab_ord' => 1, ':fa:fab:faba' => 1, ':fa:fab:faba:faba_ord' => 1, |
378 | ':fa:faa' => 1, ':fa:faa:faa_ord' => 1); |
24e8cdb8 |
379 | %Expect_Dir = (':fa' => 1, ':fa:faa' => 1, ':fa:fab' => 1, ':fa:fab:faba' => 1, |
380 | ':fb' => 1, ':fb:fba' => 1); |
7e47e6ff |
381 | File::Find::finddepth( {wanted => \&wanted, follow => 1, follow_skip => 1, no_chdir => 1, |
382 | untaint => 1 },':fa' ); |
383 | Check( scalar(keys %Expect) == 0 ); |
384 | unlink ':fa:fa_ord_sl'; |
385 | |
386 | print "# check follow_skip (directory)\n"; |
387 | CheckDie( symlink(':fa:faa',':fa:faa_sl') ); # symlink to a directory |
388 | undef $@; |
24e8cdb8 |
389 | eval {File::Find::find( {wanted => \&simple_wanted, follow => 1, follow_skip => 0, |
7e47e6ff |
390 | no_chdir => 1, untaint => 1 },':fa' );}; |
391 | print "# Died: $@"; |
392 | Check( $@ =~ m|:for_find:fa:faa: encountered a second time| ); |
393 | |
394 | undef $@; |
24e8cdb8 |
395 | eval {File::Find::find( {wanted => \&simple_wanted, follow => 1, follow_skip => 1, |
7e47e6ff |
396 | no_chdir => 1, untaint => 1 },':fa' );}; |
397 | print "# Died: $@"; |
24e8cdb8 |
398 | Check( $@ =~ m|:for_find:fa:faa: encountered a second time| ); |
7e47e6ff |
399 | |
400 | %Expect=(':fa' => 1, ':fa:fa_ord' => 1, ':fa:fsl' => 1, ':fa:fsl:fb_ord' => 1, |
401 | ':fa:fsl:fba' => 1, ':fa:fsl:fba:fba_ord' => 1, ':fa:fab' => 1, |
402 | ':fa:fab:fab_ord' => 1, ':fa:fab:faba' => 1, ':fa:fab:faba:faba_ord' => 1, |
403 | ':fa:faa' => 1, ':fa:faa:faa_ord' => 1); |
24e8cdb8 |
404 | %Expect_Dir = (':fa' => 1, ':fa:faa' => 1, ':fa:fab' => 1, ':fa:fab:faba' => 1, |
405 | ':fb' => 1, ':fb:fba' => 1); |
406 | File::Find::find( {wanted => \&wanted, follow => 1, follow_skip => 2, no_chdir => 1, |
7e47e6ff |
407 | untaint => 1},':fa' ); |
408 | Check( scalar(keys %Expect) == 0 ); |
409 | unlink ':fa:faa_sl'; |
410 | |
411 | print "# check untainting (follow)\n"; |
412 | # don't untaint at all |
413 | undef $@; |
414 | eval {File::Find::find( {wanted => \&simple_wanted, follow => 1},':fa' );}; |
415 | print "# Died: $@"; |
416 | Check( $@ =~ m|Insecure dependency| ); |
417 | chdir($cwd_untainted); |
418 | |
24e8cdb8 |
419 | undef $@; |
7e47e6ff |
420 | eval {File::Find::find( {wanted => \&simple_wanted, follow => 1, untaint => 1, |
421 | untaint_pattern => qr|^(NO_MATCH)$|},':fa' );}; |
422 | print "# Died: $@"; |
423 | Check( $@ =~ m|is still tainted| ); |
424 | chdir($cwd_untainted); |
425 | |
426 | print "# check untaint_skip (follow)\n"; |
427 | undef $@; |
24e8cdb8 |
428 | eval {File::Find::find( {wanted => \&simple_wanted, untaint => 1, untaint_skip => 1, |
7e47e6ff |
429 | untaint_pattern => qr|^(NO_MATCH)$|}, ':fa' );}; |
430 | print "# Died: $@"; |
431 | Check( $@ =~ m|insecure cwd| ); |
432 | chdir($cwd_untainted); |
433 | |
434 | } |
435 | |
436 | } else { |
437 | |
438 | MkDir( 'for_find',0770 ); |
439 | CheckDie(chdir(for_find)); |
440 | |
441 | $cwd = cwd(); # save cwd |
442 | ( $cwd_untainted ) = $cwd =~ m|^(.+)$|; # untaint it |
443 | |
444 | MkDir( 'fa',0770 ); |
445 | MkDir( 'fb',0770 ); |
446 | touch('fb/fb_ord'); |
447 | MkDir( 'fb/fba',0770 ); |
448 | touch('fb/fba/fba_ord'); |
449 | CheckDie( symlink('../fb','fa/fsl') ) if $symlink_exists; |
450 | touch('fa/fa_ord'); |
451 | |
452 | MkDir( 'fa/faa',0770 ); |
453 | touch('fa/faa/faa_ord'); |
454 | MkDir( 'fa/fab',0770 ); |
455 | touch('fa/fab/fab_ord'); |
456 | MkDir( 'fa/fab/faba',0770 ); |
457 | touch('fa/fab/faba/faba_ord'); |
458 | |
459 | %Expect = ('.' => 1, 'fsl' => 1, 'fa_ord' => 1, 'fab' => 1, 'fab_ord' => 1, |
460 | 'faba' => 1, 'faa' => 1, 'faa_ord' => 1); |
461 | delete $Expect{'fsl'} unless $symlink_exists; |
24e8cdb8 |
462 | %Expect_Dir = ('fa' => 1, 'faa' => 1, 'fab' => 1, 'faba' => 1, |
7e47e6ff |
463 | 'fb' => 1, 'fba' => 1); |
464 | delete @Expect_Dir{'fb','fba'} unless $symlink_exists; |
465 | File::Find::find( {wanted => \&wanted, untaint => 1, untaint_pattern => qr|^(.+)$|},'fa' ); |
466 | Check( scalar(keys %Expect) == 0 ); |
467 | |
468 | %Expect=('fa' => 1, 'fa/fsl' => 1, 'fa/fa_ord' => 1, 'fa/fab' => 1, |
469 | 'fa/fab/fab_ord' => 1, 'fa/fab/faba' => 1, |
470 | 'fa/fab/faba/faba_ord' => 1, 'fa/faa' => 1, 'fa/faa/faa_ord' => 1); |
471 | delete $Expect{'fa/fsl'} unless $symlink_exists; |
24e8cdb8 |
472 | %Expect_Dir = ('fa' => 1, 'fa/faa' => 1, '/fa/fab' => 1, 'fa/fab/faba' => 1, |
7e47e6ff |
473 | 'fb' => 1, 'fb/fba' => 1); |
474 | delete @Expect_Dir{'fb','fb/fba'} unless $symlink_exists; |
475 | File::Find::find( {wanted => \&wanted, no_chdir => 1, untaint => 1, untaint_pattern => qr|^(.+)$|},'fa' ); |
476 | Check( scalar(keys %Expect) == 0 ); |
477 | |
478 | %Expect=('.' => 1, './fa' => 1, './fa/fsl' => 1, './fa/fa_ord' => 1, './fa/fab' => 1, |
479 | './fa/fab/fab_ord' => 1, './fa/fab/faba' => 1, |
480 | './fa/fab/faba/faba_ord' => 1, './fa/faa' => 1, './fa/faa/faa_ord' => 1, |
481 | './fb' => 1, './fb/fba' => 1, './fb/fba/fba_ord' => 1, './fb/fb_ord' => 1); |
482 | delete $Expect{'./fa/fsl'} unless $symlink_exists; |
24e8cdb8 |
483 | %Expect_Dir = ('./fa' => 1, './fa/faa' => 1, '/fa/fab' => 1, './fa/fab/faba' => 1, |
7e47e6ff |
484 | './fb' => 1, './fb/fba' => 1); |
485 | delete @Expect_Dir{'./fb','./fb/fba'} unless $symlink_exists; |
486 | File::Find::finddepth( {wanted => \&dn_wanted , untaint => 1, untaint_pattern => qr|^(.+)$|},'.' ); |
487 | Check( scalar(keys %Expect) == 0 ); |
488 | |
489 | %Expect=('.' => 1, './fa' => 1, './fa/fsl' => 1, './fa/fa_ord' => 1, './fa/fab' => 1, |
490 | './fa/fab/fab_ord' => 1, './fa/fab/faba' => 1, |
491 | './fa/fab/faba/faba_ord' => 1, './fa/faa' => 1, './fa/faa/faa_ord' => 1, |
492 | './fb' => 1, './fb/fba' => 1, './fb/fba/fba_ord' => 1, './fb/fb_ord' => 1); |
493 | delete $Expect{'./fa/fsl'} unless $symlink_exists; |
24e8cdb8 |
494 | %Expect_Dir = ('./fa' => 1, './fa/faa' => 1, '/fa/fab' => 1, './fa/fab/faba' => 1, |
7e47e6ff |
495 | './fb' => 1, './fb/fba' => 1); |
496 | delete @Expect_Dir{'./fb','./fb/fba'} unless $symlink_exists; |
497 | File::Find::finddepth( {wanted => \&d_wanted, no_chdir => 1, untaint => 1, untaint_pattern => qr|^(.+)$| },'.' ); |
498 | Check( scalar(keys %Expect) == 0 ); |
499 | |
500 | # untaint, preprocess and postprocess tests below added by Thomas Wegner, 17-05-2001 |
501 | |
502 | print "# check untainting (no follow)\n"; |
503 | # don't untaint at all |
504 | undef $@; |
505 | eval {File::Find::find( {wanted => \&simple_wanted},'fa' );}; |
506 | print "# Died: $@"; |
507 | Check( $@ =~ m|Insecure dependency| ); |
508 | chdir($cwd_untainted); |
509 | |
510 | undef $@; |
511 | eval {File::Find::find( {wanted => \&simple_wanted, untaint => 1, |
24e8cdb8 |
512 | untaint_pattern => qr|^(NO_MATCH)$|},'fa' );}; |
7e47e6ff |
513 | print "# Died: $@"; |
514 | Check( $@ =~ m|is still tainted| ); |
515 | chdir($cwd_untainted); |
516 | |
517 | print "# check untaint_skip (no follow)\n"; |
518 | undef $@; |
24e8cdb8 |
519 | eval {File::Find::find( {wanted => \&simple_wanted, untaint => 1, untaint_skip => 1, |
7e47e6ff |
520 | untaint_pattern => qr|^(NO_MATCH)$|}, 'fa' );}; |
521 | print "# Died: $@"; |
522 | Check( $@ =~ m|insecure cwd| ); |
523 | chdir($cwd_untainted); |
524 | |
525 | print "# check preprocess\n"; |
526 | %Expect=( |
24e8cdb8 |
527 | '.' => {fa => 1, fb => 1}, |
7e47e6ff |
528 | './fa' => {faa => 1, fab => 1, fa_ord => 1}, |
529 | './fa/faa' => {faa_ord => 1}, |
530 | './fa/fab' => {faba => 1, fab_ord => 1}, |
24e8cdb8 |
531 | './fa/fab/faba' => {faba_ord => 1}, |
7e47e6ff |
532 | './fb' => {fba => 1, fb_ord => 1}, |
533 | './fb/fba' => {fba_ord => 1} |
534 | ); |
535 | |
24e8cdb8 |
536 | File::Find::find( {wanted => \&noop_wanted, preprocess => \&my_preprocess, untaint => 1, |
7e47e6ff |
537 | untaint_pattern => qr|^(.+)$|}, '.' ); |
538 | Check( scalar(keys %Expect) == 0 ); |
539 | |
540 | print "# check postprocess\n"; |
541 | %Expect=('.' => 1, './fa' => 1, './fa/faa' => 1, './fa/fab' => 1, './fa/fab/faba' => 1, './fb' => 1, |
542 | './fb/fba' => 1 ); |
24e8cdb8 |
543 | File::Find::find( {wanted => \&noop_wanted, postprocess => \&my_postprocess, untaint => 1, |
7e47e6ff |
544 | untaint_pattern => qr|^(.+)$|}, '.' ); |
545 | Check( scalar(keys %Expect) == 0 ); |
546 | |
547 | # Verify that File::Find::find will call wanted even if the topdir of |
548 | # is a symlink to a directory, and it shouldn't follow the link |
549 | # unless follow is set, which it isn't in this case |
550 | %Expect = ('fsl' => 1); |
551 | %Expect_Dir = (); |
552 | File::Find::find( {wanted => \&wanted, untaint => 1},'fa/fsl' ); |
553 | Check( scalar(keys %Expect) == 0 ); |
554 | |
555 | if ( $symlink_exists ) { |
556 | $FastFileTests_OK= 1; |
557 | %Expect=('.' => 1, 'fa_ord' => 1, 'fsl' => 1, 'fb_ord' => 1, 'fba' => 1, |
558 | 'fba_ord' => 1, 'fab' => 1, 'fab_ord' => 1, 'faba' => 1, 'faa' => 1, |
559 | 'faa_ord' => 1); |
24e8cdb8 |
560 | %Expect_Dir = ('fa' => 1, 'fa/faa' => 1, '/fa/fab' => 1, 'fa/fab/faba' => 1, |
7e47e6ff |
561 | 'fb' => 1, 'fb/fba' => 1); |
562 | File::Find::find( {wanted => \&wanted, follow_fast => 1, untaint => 1, untaint_pattern => qr|^(.+)$|},'fa' ); |
563 | Check( scalar(keys %Expect) == 0 ); |
564 | |
565 | %Expect=('fa' => 1, 'fa/fa_ord' => 1, 'fa/fsl' => 1, 'fa/fsl/fb_ord' => 1, |
566 | 'fa/fsl/fba' => 1, 'fa/fsl/fba/fba_ord' => 1, 'fa/fab' => 1, |
567 | 'fa/fab/fab_ord' => 1, 'fa/fab/faba' => 1, 'fa/fab/faba/faba_ord' => 1, |
568 | 'fa/faa' => 1, 'fa/faa/faa_ord' => 1); |
24e8cdb8 |
569 | %Expect_Dir = ('fa' => 1, 'fa/faa' => 1, '/fa/fab' => 1, 'fa/fab/faba' => 1, |
7e47e6ff |
570 | 'fb' => 1, 'fb/fba' => 1); |
24e8cdb8 |
571 | File::Find::find( {wanted => \&wanted, follow_fast => 1, no_chdir => 1, untaint => 1, |
7e47e6ff |
572 | untaint_pattern => qr|^(.+)$|},'fa' ); |
573 | Check( scalar(keys %Expect) == 0 ); |
574 | |
575 | %Expect=('fa' => 1, 'fa/fa_ord' => 1, 'fa/fsl' => 1, 'fa/fsl/fb_ord' => 1, |
576 | 'fa/fsl/fba' => 1, 'fa/fsl/fba/fba_ord' => 1, 'fa/fab' => 1, |
577 | 'fa/fab/fab_ord' => 1, 'fa/fab/faba' => 1, 'fa/fab/faba/faba_ord' => 1, |
578 | 'fa/faa' => 1, 'fa/faa/faa_ord' => 1); |
24e8cdb8 |
579 | %Expect_Dir = ('fa' => 1, 'fa/faa' => 1, '/fa/fab' => 1, 'fa/fab/faba' => 1, |
580 | 'fb' => 1, 'fb/fba' => 1); |
581 | File::Find::finddepth( {wanted => \&dn_wanted, follow_fast => 1, untaint => 1, |
7e47e6ff |
582 | untaint_pattern => qr|^(.+)$|},'fa' ); |
583 | Check( scalar(keys %Expect) == 0 ); |
584 | |
585 | %Expect=('fa' => 1, 'fa/fa_ord' => 1, 'fa/fsl' => 1, 'fa/fsl/fb_ord' => 1, |
586 | 'fa/fsl/fba' => 1, 'fa/fsl/fba/fba_ord' => 1, 'fa/fab' => 1, |
587 | 'fa/fab/fab_ord' => 1, 'fa/fab/faba' => 1, 'fa/fab/faba/faba_ord' => 1, |
588 | 'fa/faa' => 1, 'fa/faa/faa_ord' => 1); |
24e8cdb8 |
589 | %Expect_Dir = ('fa' => 1, 'fa/faa' => 1, '/fa/fab' => 1, 'fa/fab/faba' => 1, |
7e47e6ff |
590 | 'fb' => 1, 'fb/fba' => 1); |
24e8cdb8 |
591 | File::Find::finddepth( {wanted => \&d_wanted, follow_fast => 1, no_chdir => 1, |
7e47e6ff |
592 | untaint => 1, untaint_pattern => qr|^(.+)$|},'fa' ); |
593 | Check( scalar(keys %Expect) == 0 ); |
594 | |
595 | # tests below added by Thomas Wegner, 17-05-2001 |
596 | |
597 | print "# check dangling symbolic links\n"; |
598 | MkDir( 'dangling_dir',0770 ); |
599 | CheckDie( symlink('dangling_dir','dangling_dir_sl') ); |
600 | rmdir 'dangling_dir'; |
601 | touch('dangling_file'); |
602 | CheckDie( symlink('../dangling_file','fa/dangling_file_sl') ); |
603 | unlink 'dangling_file'; |
604 | |
605 | %Expect=('.' => 1, 'fa_ord' => 1, 'fsl' => 1, 'fb_ord' => 1, 'fba' => 1, |
606 | 'fba_ord' => 1, 'fab' => 1, 'fab_ord' => 1, 'faba' => 1, 'faba_ord' => 1, |
607 | 'faa' => 1, 'faa_ord' => 1); |
24e8cdb8 |
608 | %Expect_Dir = ('fa' => 1, 'fa/faa' => 1, 'fa/fab' => 1, 'fa/fab/faba' => 1, |
7e47e6ff |
609 | 'fb' => 1, 'fb/fba' => 1); |
610 | undef $warn_msg; |
24e8cdb8 |
611 | File::Find::find( {wanted => \&d_wanted, follow => 1, untaint => 1, |
7e47e6ff |
612 | untaint_pattern => qr|^(.+)$|}, 'dangling_dir_sl', 'fa' ); |
24e8cdb8 |
613 | Check( $warn_msg =~ m|dangling_dir_sl is a dangling symbolic link| ); |
7e47e6ff |
614 | unlink 'fa/dangling_file_sl', 'dangling_dir_sl'; |
615 | |
616 | print "# check recursion\n"; |
617 | CheckDie( symlink('../faa','fa/faa/faa_sl') ); |
618 | undef $@; |
24e8cdb8 |
619 | eval {File::Find::find( {wanted => \&simple_wanted, follow => 1, no_chdir => 1, |
7e47e6ff |
620 | untaint => 1, untaint_pattern => qr|^(.+)$|},'fa' ); }; |
621 | print "# Died: $@"; |
24e8cdb8 |
622 | Check( $@ =~ m|for_find/fa/faa/faa_sl is a recursive symbolic link| ); |
623 | unlink 'fa/faa/faa_sl'; |
624 | |
7e47e6ff |
625 | print "# check follow_skip (file)\n"; |
626 | CheckDie( symlink('./fa_ord','fa/fa_ord_sl') ); # symlink to a file |
627 | undef $@; |
24e8cdb8 |
628 | eval {File::Find::finddepth( {wanted => \&simple_wanted, follow => 1, follow_skip => 0, no_chdir => 1, |
7e47e6ff |
629 | untaint => 1, untaint_pattern => qr|^(.+)$|},'fa' );}; |
630 | print "# Died: $@"; |
631 | Check( $@ =~ m|for_find/fa/fa_ord encountered a second time| ); |
24e8cdb8 |
632 | |
7e47e6ff |
633 | %Expect=('fa' => 1, 'fa/fa_ord' => 1, 'fa/fsl' => 1, 'fa/fsl/fb_ord' => 1, |
634 | 'fa/fsl/fba' => 1, 'fa/fsl/fba/fba_ord' => 1, 'fa/fab' => 1, |
635 | 'fa/fab/fab_ord' => 1, 'fa/fab/faba' => 1, 'fa/fab/faba/faba_ord' => 1, |
636 | 'fa/faa' => 1, 'fa/faa/faa_ord' => 1); |
24e8cdb8 |
637 | %Expect_Dir = ('fa' => 1, 'fa/faa' => 1, '/fa/fab' => 1, 'fa/fab/faba' => 1, |
638 | 'fb' => 1, 'fb/fba' => 1); |
639 | File::Find::finddepth( {wanted => \&wanted, follow => 1, follow_skip => 1, no_chdir => 1, |
7e47e6ff |
640 | untaint => 1, untaint_pattern => qr|^(.+)$|},'fa' ); |
641 | Check( scalar(keys %Expect) == 0 ); |
642 | unlink 'fa/fa_ord_sl'; |
643 | |
644 | print "# check follow_skip (directory)\n"; |
645 | CheckDie( symlink('./faa','fa/faa_sl') ); # symlink to a directory |
646 | undef $@; |
647 | eval {File::Find::find( {wanted => \&simple_wanted, follow => 1, follow_skip => 0, no_chdir => 1, |
648 | untaint => 1, untaint_pattern => qr|^(.+)$|},'fa' );}; |
649 | print "# Died: $@"; |
650 | Check( $@ =~ m|for_find/fa/faa encountered a second time| ); |
651 | |
652 | undef $@; |
653 | eval {File::Find::find( {wanted => \&simple_wanted, follow => 1, follow_skip => 1, no_chdir => 1, |
654 | untaint => 1, untaint_pattern => qr|^(.+)$|},'fa' );}; |
655 | print "# Died: $@"; |
656 | Check( $@ =~ m|for_find/fa/faa encountered a second time| ); |
657 | |
658 | %Expect=('fa' => 1, 'fa/fa_ord' => 1, 'fa/fsl' => 1, 'fa/fsl/fb_ord' => 1, |
659 | 'fa/fsl/fba' => 1, 'fa/fsl/fba/fba_ord' => 1, 'fa/fab' => 1, |
660 | 'fa/fab/fab_ord' => 1, 'fa/fab/faba' => 1, 'fa/fab/faba/faba_ord' => 1, |
661 | 'fa/faa' => 1, 'fa/faa/faa_ord' => 1); |
24e8cdb8 |
662 | %Expect_Dir = ('fa' => 1, 'fa/faa' => 1, '/fa/fab' => 1, 'fa/fab/faba' => 1, |
663 | 'fb' => 1, 'fb/fba' => 1); |
7e47e6ff |
664 | File::Find::find( {wanted => \&wanted, follow => 1, follow_skip => 2, no_chdir => 1, |
665 | untaint => 1, untaint_pattern => qr|^(.+)$|},'fa' ); |
666 | Check( scalar(keys %Expect) == 0 ); |
667 | unlink 'fa/faa_sl'; |
668 | |
669 | print "# check untainting (follow)\n"; |
670 | # don't untaint at all |
671 | undef $@; |
672 | eval {File::Find::find( {wanted => \&simple_wanted, follow => 1},'fa' );}; |
673 | print "# Died: $@"; |
674 | Check( $@ =~ m|Insecure dependency| ); |
675 | chdir($cwd_untainted); |
676 | |
24e8cdb8 |
677 | undef $@; |
7e47e6ff |
678 | eval {File::Find::find( {wanted => \&simple_wanted, follow => 1, untaint => 1, |
679 | untaint_pattern => qr|^(NO_MATCH)$|},'fa' );}; |
680 | print "# Died: $@"; |
681 | Check( $@ =~ m|is still tainted| ); |
682 | chdir($cwd_untainted); |
683 | |
684 | print "# check untaint_skip (follow)\n"; |
685 | undef $@; |
24e8cdb8 |
686 | eval {File::Find::find( {wanted => \&simple_wanted, untaint => 1, untaint_skip => 1, |
7e47e6ff |
687 | untaint_pattern => qr|^(NO_MATCH)$|}, 'fa' );}; |
688 | print "# Died: $@"; |
689 | Check( $@ =~ m|insecure cwd| ); |
690 | chdir($cwd_untainted); |
691 | |
692 | } |
81793b90 |
693 | } |
694 | |
695 | print "# of cases: $case\n"; |