Skip to content

Commit a59b5ab

Browse files
GeopJrHertzDevil
andauthored
Fix Globber.constant_entry? matching patterns (#13955)
Co-authored-by: Quinton Miller <[email protected]>
1 parent 35eb340 commit a59b5ab

File tree

4 files changed

+80
-38
lines changed

4 files changed

+80
-38
lines changed

spec/std/dir_spec.cr

Lines changed: 77 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -193,15 +193,15 @@ describe "Dir" do
193193

194194
describe "glob" do
195195
it "tests glob with a single pattern" do
196-
Dir["#{datapath}/dir/*.txt"].sort.should eq [
196+
Dir["#{Path[datapath].to_posix}/dir/*.txt"].sort.should eq [
197197
datapath("dir", "f1.txt"),
198198
datapath("dir", "f2.txt"),
199199
datapath("dir", "g2.txt"),
200200
].sort
201201
end
202202

203203
it "tests glob with multiple patterns" do
204-
Dir["#{datapath}/dir/*.txt", "#{datapath}/dir/subdir/*.txt"].sort.should eq [
204+
Dir["#{Path[datapath].to_posix}/dir/*.txt", "#{Path[datapath].to_posix}/dir/subdir/*.txt"].sort.should eq [
205205
datapath("dir", "f1.txt"),
206206
datapath("dir", "f2.txt"),
207207
datapath("dir", "g2.txt"),
@@ -211,7 +211,7 @@ describe "Dir" do
211211

212212
it "tests glob with a single pattern with block" do
213213
result = [] of String
214-
Dir.glob("#{datapath}/dir/*.txt") do |filename|
214+
Dir.glob("#{Path[datapath].to_posix}/dir/*.txt") do |filename|
215215
result << filename
216216
end
217217
result.sort.should eq([
@@ -222,19 +222,19 @@ describe "Dir" do
222222
end
223223

224224
it "tests a recursive glob" do
225-
Dir["#{datapath}/dir/**/*.txt"].sort.should eq [
225+
Dir["#{Path[datapath].to_posix}/dir/**/*.txt"].sort.should eq [
226226
datapath("dir", "f1.txt"),
227227
datapath("dir", "f2.txt"),
228228
datapath("dir", "g2.txt"),
229229
datapath("dir", "subdir", "f1.txt"),
230230
datapath("dir", "subdir", "subdir2", "f2.txt"),
231231
].sort
232232

233-
Dir["#{datapath}/dir/**/subdir2/f2.txt"].sort.should eq [
233+
Dir["#{Path[datapath].to_posix}/dir/**/subdir2/f2.txt"].sort.should eq [
234234
datapath("dir", "subdir", "subdir2", "f2.txt"),
235235
].sort
236236

237-
Dir["#{datapath}/dir/**/subdir2/*.txt"].sort.should eq [
237+
Dir["#{Path[datapath].to_posix}/dir/**/subdir2/*.txt"].sort.should eq [
238238
datapath("dir", "subdir", "subdir2", "f2.txt"),
239239
].sort
240240
end
@@ -274,15 +274,15 @@ describe "Dir" do
274274
end
275275

276276
it "tests a recursive glob with '?'" do
277-
Dir["#{datapath}/dir/f?.tx?"].sort.should eq [
277+
Dir["#{Path[datapath].to_posix}/dir/f?.tx?"].sort.should eq [
278278
datapath("dir", "f1.txt"),
279279
datapath("dir", "f2.txt"),
280280
datapath("dir", "f3.txx"),
281281
].sort
282282
end
283283

284284
it "tests a recursive glob with alternation" do
285-
Dir["#{datapath}/{dir,dir/subdir}/*.txt"].sort.should eq [
285+
Dir["#{Path[datapath].to_posix}/{dir,dir/subdir}/*.txt"].sort.should eq [
286286
datapath("dir", "f1.txt"),
287287
datapath("dir", "f2.txt"),
288288
datapath("dir", "g2.txt"),
@@ -291,7 +291,7 @@ describe "Dir" do
291291
end
292292

293293
it "tests a glob with recursion inside alternation" do
294-
Dir["#{datapath}/dir/{**/*.txt,**/*.txx}"].sort.should eq [
294+
Dir["#{Path[datapath].to_posix}/dir/{**/*.txt,**/*.txx}"].sort.should eq [
295295
datapath("dir", "f1.txt"),
296296
datapath("dir", "f2.txt"),
297297
datapath("dir", "f3.txx"),
@@ -302,15 +302,56 @@ describe "Dir" do
302302
end
303303

304304
it "tests a recursive glob with nested alternations" do
305-
Dir["#{datapath}/dir/{?1.*,{f,g}2.txt}"].sort.should eq [
305+
Dir["#{Path[datapath].to_posix}/dir/{?1.*,{f,g}2.txt}"].sort.should eq [
306306
datapath("dir", "f1.txt"),
307307
datapath("dir", "f2.txt"),
308308
datapath("dir", "g2.txt"),
309309
].sort
310310
end
311311

312+
it "tests with []" do
313+
Dir["#{Path[datapath].to_posix}/dir/[a-z][0-9].txt"].sort.should eq [
314+
datapath("dir", "f1.txt"),
315+
datapath("dir", "f2.txt"),
316+
datapath("dir", "g2.txt"),
317+
].sort
318+
end
319+
320+
it "tests with {}" do
321+
Dir["#{Path[datapath].to_posix}/dir/{f,g}{1,2,3}.tx{t,x}"].sort.should eq [
322+
datapath("dir", "f1.txt"),
323+
datapath("dir", "f2.txt"),
324+
datapath("dir", "f3.txx"),
325+
datapath("dir", "g2.txt"),
326+
].sort
327+
end
328+
329+
{% if flag?(:windows) %}
330+
pending "tests with \\"
331+
{% else %}
332+
it "tests with \\" do
333+
with_tempfile "glob-escape-pattern" do |path|
334+
Dir.mkdir_p path
335+
Dir.cd(path) do
336+
File.touch "g1.txt"
337+
File.touch %q(\g3)
338+
File.touch %q(\g4*)
339+
340+
Dir[%q(\\g*)].sort.should eq [
341+
"\\g3",
342+
"\\g4*",
343+
].sort
344+
345+
Dir[%q(*g?\*)].sort.should eq [
346+
"\\g4*",
347+
].sort
348+
end
349+
end
350+
end
351+
{% end %}
352+
312353
it "tests with *" do
313-
Dir["#{datapath}/dir/*"].sort.should eq [
354+
Dir["#{Path[datapath].to_posix}/dir/*"].sort.should eq [
314355
datapath("dir", "dots"),
315356
datapath("dir", "f1.txt"),
316357
datapath("dir", "f2.txt"),
@@ -322,7 +363,7 @@ describe "Dir" do
322363
end
323364

324365
it "tests with ** (same as *)" do
325-
Dir["#{datapath}/dir/**"].sort.should eq [
366+
Dir["#{Path[datapath].to_posix}/dir/**"].sort.should eq [
326367
datapath("dir", "dots"),
327368
datapath("dir", "f1.txt"),
328369
datapath("dir", "f2.txt"),
@@ -334,7 +375,7 @@ describe "Dir" do
334375
end
335376

336377
it "tests with */" do
337-
Dir["#{datapath}/dir/*/"].sort.should eq [
378+
Dir["#{Path[datapath].to_posix}/dir/*/"].sort.should eq [
338379
datapath("dir", "dots", ""),
339380
datapath("dir", "subdir", ""),
340381
datapath("dir", "subdir2", ""),
@@ -350,15 +391,15 @@ describe "Dir" do
350391
end
351392

352393
it "tests with relative path" do
353-
Dir["#{datapath}/dir/*/"].sort.should eq [
394+
Dir["#{Path[datapath].to_posix}/dir/*/"].sort.should eq [
354395
datapath("dir", "dots", ""),
355396
datapath("dir", "subdir", ""),
356397
datapath("dir", "subdir2", ""),
357398
].sort
358399
end
359400

360401
it "tests with relative path (starts with .)" do
361-
Dir["./#{datapath}/dir/*/"].sort.should eq [
402+
Dir["./#{Path[datapath].to_posix}/dir/*/"].sort.should eq [
362403
File.join(".", "spec", "std", "data", "dir", "dots", ""),
363404
File.join(".", "spec", "std", "data", "dir", "subdir", ""),
364405
File.join(".", "spec", "std", "data", "dir", "subdir2", ""),
@@ -368,7 +409,7 @@ describe "Dir" do
368409
it "tests with relative path (starts with ..)" do
369410
Dir.cd(datapath) do
370411
base_path = Path["..", "data", "dir"]
371-
Dir["#{base_path}/*/"].sort.should eq [
412+
Dir["#{base_path.to_posix}/*/"].sort.should eq [
372413
base_path.join("dots", "").to_s,
373414
base_path.join("subdir", "").to_s,
374415
base_path.join("subdir2", "").to_s,
@@ -394,11 +435,11 @@ describe "Dir" do
394435
File.symlink(datapath("dir", "f1.txt"), link)
395436
File.symlink(datapath("dir", "nonexisting"), non_link)
396437

397-
Dir["#{path}/*_link.txt"].sort.should eq [
438+
Dir["#{Path[path].to_posix}/*_link.txt"].sort.should eq [
398439
link.to_s,
399440
non_link.to_s,
400441
].sort
401-
Dir["#{path}/non_link.txt"].should eq [non_link.to_s]
442+
Dir["#{Path[path].to_posix}/non_link.txt"].should eq [non_link.to_s]
402443
end
403444
end
404445

@@ -414,8 +455,8 @@ describe "Dir" do
414455
File.write(non_link, "")
415456
File.symlink(target, link_dir)
416457

417-
Dir.glob("#{path}/glob/*/a.txt").sort.should eq [] of String
418-
Dir.glob("#{path}/glob/*/a.txt", follow_symlinks: true).sort.should eq [
458+
Dir.glob("#{Path[path].to_posix}/glob/*/a.txt").sort.should eq [] of String
459+
Dir.glob("#{Path[path].to_posix}/glob/*/a.txt", follow_symlinks: true).sort.should eq [
419460
File.join(path, "glob", "dir", "a.txt"),
420461
]
421462
end
@@ -435,27 +476,27 @@ describe "Dir" do
435476
end
436477

437478
it "pattern ending with .." do
438-
Dir["#{datapath}/dir/.."].sort.should eq [
479+
Dir["#{Path[datapath].to_posix}/dir/.."].sort.should eq [
439480
datapath("dir", ".."),
440481
].sort
441482
end
442483

443484
it "pattern ending with */.." do
444-
Dir["#{datapath}/dir/*/.."].sort.should eq [
485+
Dir["#{Path[datapath].to_posix}/dir/*/.."].sort.should eq [
445486
datapath("dir", "dots", ".."),
446487
datapath("dir", "subdir", ".."),
447488
datapath("dir", "subdir2", ".."),
448489
].sort
449490
end
450491

451492
it "pattern ending with ." do
452-
Dir["#{datapath}/dir/."].sort.should eq [
493+
Dir["#{Path[datapath].to_posix}/dir/."].sort.should eq [
453494
datapath("dir", "."),
454495
].sort
455496
end
456497

457498
it "pattern ending with */." do
458-
Dir["#{datapath}/dir/*/."].sort.should eq [
499+
Dir["#{Path[datapath].to_posix}/dir/*/."].sort.should eq [
459500
datapath("dir", "dots", "."),
460501
datapath("dir", "subdir", "."),
461502
datapath("dir", "subdir2", "."),
@@ -464,26 +505,26 @@ describe "Dir" do
464505

465506
context "match: :dot_files / match_hidden" do
466507
it "matches dot files" do
467-
Dir.glob("#{datapath}/dir/dots/**/*", match: :dot_files).sort.should eq [
508+
Dir.glob("#{Path[datapath].to_posix}/dir/dots/**/*", match: :dot_files).sort.should eq [
468509
datapath("dir", "dots", ".dot.hidden"),
469510
datapath("dir", "dots", ".hidden"),
470511
datapath("dir", "dots", ".hidden", "f1.txt"),
471512
].sort
472-
Dir.glob("#{datapath}/dir/dots/**/*", match_hidden: true).sort.should eq [
513+
Dir.glob("#{Path[datapath].to_posix}/dir/dots/**/*", match_hidden: true).sort.should eq [
473514
datapath("dir", "dots", ".dot.hidden"),
474515
datapath("dir", "dots", ".hidden"),
475516
datapath("dir", "dots", ".hidden", "f1.txt"),
476517
].sort
477518
end
478519

479520
it "ignores hidden files" do
480-
Dir.glob("#{datapath}/dir/dots/*", match: :none).should be_empty
481-
Dir.glob("#{datapath}/dir/dots/*", match_hidden: false).should be_empty
521+
Dir.glob("#{Path[datapath].to_posix}/dir/dots/*", match: :none).should be_empty
522+
Dir.glob("#{Path[datapath].to_posix}/dir/dots/*", match_hidden: false).should be_empty
482523
end
483524

484525
it "ignores hidden files recursively" do
485-
Dir.glob("#{datapath}/dir/dots/**/*", match: :none).should be_empty
486-
Dir.glob("#{datapath}/dir/dots/**/*", match_hidden: false).should be_empty
526+
Dir.glob("#{Path[datapath].to_posix}/dir/dots/**/*", match: :none).should be_empty
527+
Dir.glob("#{Path[datapath].to_posix}/dir/dots/**/*", match_hidden: false).should be_empty
487528
end
488529
end
489530

@@ -534,10 +575,10 @@ describe "Dir" do
534575
expected_hidden = (expected + [hidden_txt, hidden_dir, inside_hidden]).sort!
535576
expected_system_hidden = (expected_hidden + [system_hidden_txt, system_hidden_dir, inside_system_hidden]).sort!
536577

537-
Dir.glob("#{path}/**/*", match: :none).sort.should eq(expected)
538-
Dir.glob("#{path}/**/*", match: :native_hidden).sort.should eq(expected_hidden)
539-
Dir.glob("#{path}/**/*", match: :os_hidden).sort.should eq(expected)
540-
Dir.glob("#{path}/**/*", match: File::MatchOptions[NativeHidden, OSHidden]).sort.should eq(expected_system_hidden)
578+
Dir.glob("#{Path[path].to_posix}/**/*", match: :none).sort.should eq(expected)
579+
Dir.glob("#{Path[path].to_posix}/**/*", match: :native_hidden).sort.should eq(expected_hidden)
580+
Dir.glob("#{Path[path].to_posix}/**/*", match: :os_hidden).sort.should eq(expected)
581+
Dir.glob("#{Path[path].to_posix}/**/*", match: File::MatchOptions[NativeHidden, OSHidden]).sort.should eq(expected_system_hidden)
541582
end
542583
end
543584
{% end %}
@@ -550,8 +591,8 @@ describe "Dir" do
550591
]
551592

552593
it "posix path" do
553-
Dir[Path.posix(datapath, "dir", "*.txt")].sort.should eq expected
554-
Dir[[Path.posix(datapath, "dir", "*.txt")]].sort.should eq expected
594+
Dir[Path.posix(Path[datapath].to_posix, "dir", "*.txt")].sort.should eq expected
595+
Dir[[Path.posix(Path[datapath].to_posix, "dir", "*.txt")]].sort.should eq expected
555596
end
556597

557598
it "windows path" do

src/compiler/crystal/command/format.cr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ class Crystal::Command
120120
format_file filename
121121
end
122122
elsif Dir.exists?(filename)
123-
filename = filename.chomp('/')
123+
filename = ::Path[filename.chomp('/')].to_posix
124124
filenames = Dir["#{filename}/**/*.cr"]
125125
format_many filenames
126126
else

src/compiler/crystal/command/spec.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class Crystal::Command
6060
locations << {file, line}
6161
else
6262
if Dir.exists?(filename)
63+
filename = ::Path[filename].to_posix
6364
target_filenames.concat Dir["#{filename}/**/*_spec.cr"]
6465
elsif File.file?(filename)
6566
target_filenames << filename

src/dir/glob.cr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ class Dir
223223

224224
private def self.constant_entry?(file)
225225
file.each_char do |char|
226-
return false if char.in?('*', '?')
226+
return false if char.in?('*', '?', '[', '\\')
227227
end
228228

229229
true

0 commit comments

Comments
 (0)