github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/io/fs/glob_test.go (about) 1 // Copyright 2020 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package fs_test 6 7 import ( 8 . "io/fs" 9 "os" 10 "path" 11 "strings" 12 "testing" 13 ) 14 15 var globTests = []struct { 16 fs FS 17 pattern, result string 18 }{ 19 {os.DirFS("."), "glob.go", "glob.go"}, 20 {os.DirFS("."), "gl?b.go", "glob.go"}, 21 {os.DirFS("."), `gl\ob.go`, "glob.go"}, 22 {os.DirFS("."), "*", "glob.go"}, 23 {os.DirFS(".."), "*/glob.go", "fs/glob.go"}, 24 } 25 26 func TestGlob(t *testing.T) { 27 for _, tt := range globTests { 28 matches, err := Glob(tt.fs, tt.pattern) 29 if err != nil { 30 t.Errorf("Glob error for %q: %s", tt.pattern, err) 31 continue 32 } 33 if !contains(matches, tt.result) { 34 t.Errorf("Glob(%#q) = %#v want %v", tt.pattern, matches, tt.result) 35 } 36 } 37 for _, pattern := range []string{"no_match", "../*/no_match", `\*`} { 38 matches, err := Glob(os.DirFS("."), pattern) 39 if err != nil { 40 t.Errorf("Glob error for %q: %s", pattern, err) 41 continue 42 } 43 if len(matches) != 0 { 44 t.Errorf("Glob(%#q) = %#v want []", pattern, matches) 45 } 46 } 47 } 48 49 func TestGlobError(t *testing.T) { 50 bad := []string{`[]`, `nonexist/[]`} 51 for _, pattern := range bad { 52 _, err := Glob(os.DirFS("."), pattern) 53 if err != path.ErrBadPattern { 54 t.Errorf("Glob(fs, %#q) returned err=%v, want path.ErrBadPattern", pattern, err) 55 } 56 } 57 } 58 59 func TestCVE202230630(t *testing.T) { 60 // Prior to CVE-2022-30630, a stack exhaustion would occur given a large 61 // number of separators. There is now a limit of 10,000. 62 _, err := Glob(os.DirFS("."), "/*"+strings.Repeat("/", 10001)) 63 if err != path.ErrBadPattern { 64 t.Fatalf("Glob returned err=%v, want %v", err, path.ErrBadPattern) 65 } 66 } 67 68 // contains reports whether vector contains the string s. 69 func contains(vector []string, s string) bool { 70 for _, elem := range vector { 71 if elem == s { 72 return true 73 } 74 } 75 return false 76 } 77 78 type globOnly struct{ GlobFS } 79 80 func (globOnly) Open(name string) (File, error) { return nil, ErrNotExist } 81 82 func TestGlobMethod(t *testing.T) { 83 check := func(desc string, names []string, err error) { 84 t.Helper() 85 if err != nil || len(names) != 1 || names[0] != "hello.txt" { 86 t.Errorf("Glob(%s) = %v, %v, want %v, nil", desc, names, err, []string{"hello.txt"}) 87 } 88 } 89 90 // Test that ReadDir uses the method when present. 91 names, err := Glob(globOnly{testFsys}, "*.txt") 92 check("readDirOnly", names, err) 93 94 // Test that ReadDir uses Open when the method is not present. 95 names, err = Glob(openOnly{testFsys}, "*.txt") 96 check("openOnly", names, err) 97 }