From 53f4950eea0287272aac3c3f7b2064742462dbc6 Mon Sep 17 00:00:00 2001 From: Dan Willemsen Date: Mon, 25 Jul 2016 18:40:02 -0700 Subject: [PATCH] Prevent glob from accessing hidden files Hidden files are often source control related (".git", ".repo", etc) or editor related (vim's .*.swp), so are not guaranteed to exist, and may be temporary. The build system shouldn't be using these files by default. If the glob pattern explicitly uses "." at the beginning of a path component, allow returning hidden files for that component. Because of this behavior, non-wildcard globs remain unchanged. The one behavior that cannot be handled anymore is including hidden files in recursive globs. Change-Id: I583c506e9a18ed2ff7ca011a791165d9582de90f --- pathtools/glob.go | 23 +++++++++++++++++++++++ pathtools/glob_test.go | 22 ++++++++++++++++++++++ pathtools/testdata/.test/.ing | 0 pathtools/testdata/.test/a | 0 pathtools/testdata/.testing | 0 5 files changed, 45 insertions(+) create mode 100644 pathtools/testdata/.test/.ing create mode 100644 pathtools/testdata/.test/a create mode 100644 pathtools/testdata/.testing diff --git a/pathtools/glob.go b/pathtools/glob.go index 0b9ea14..286d933 100644 --- a/pathtools/glob.go +++ b/pathtools/glob.go @@ -131,6 +131,9 @@ func glob(pattern string, hasRecursive bool) (matches, dirs []string, err error) if err != nil { return nil, nil, err } + if file[0] != '.' { + newMatches = filterDotFiles(newMatches) + } matches = append(matches, newMatches...) } } @@ -170,6 +173,11 @@ func walkAllDirs(dir string) (dirs []string, err error) { } if info.Mode().IsDir() { + name := info.Name() + if name[0] == '.' && name != "." { + return filepath.SkipDir + } + dirs = append(dirs, path) } return nil @@ -203,6 +211,21 @@ matchLoop: return ret, nil } +// filterDotFiles filters out files that start with '.' +func filterDotFiles(matches []string) []string { + ret := make([]string, 0, len(matches)) + + for _, match := range matches { + _, name := filepath.Split(match) + if name[0] == '.' { + continue + } + ret = append(ret, match) + } + + return ret +} + // match returns true if name matches pattern using the same rules as filepath.Match, but supporting // hierarchical patterns (a/*) and recursive globs (**). func match(pattern, name string) (bool, error) { diff --git a/pathtools/glob_test.go b/pathtools/glob_test.go index b082267..803cb6b 100644 --- a/pathtools/glob_test.go +++ b/pathtools/glob_test.go @@ -417,6 +417,28 @@ var globTestCases = []struct { excludes: []string{"**/**"}, err: GlobLastRecursiveErr, }, + + // If names are excluded by default, but referenced explicitly, they should return results + { + pattern: ".test/*", + matches: []string{".test/a"}, + dirs: []string{".test"}, + }, + { + pattern: ".t*/a", + matches: []string{".test/a"}, + dirs: []string{".", ".test"}, + }, + { + pattern: ".*/.*", + matches: []string{".test/.ing"}, + dirs: []string{".", ".test"}, + }, + { + pattern: ".t*", + matches: []string{".test", ".testing"}, + dirs: []string{"."}, + }, } func TestGlob(t *testing.T) { diff --git a/pathtools/testdata/.test/.ing b/pathtools/testdata/.test/.ing new file mode 100644 index 0000000..e69de29 diff --git a/pathtools/testdata/.test/a b/pathtools/testdata/.test/a new file mode 100644 index 0000000..e69de29 diff --git a/pathtools/testdata/.testing b/pathtools/testdata/.testing new file mode 100644 index 0000000..e69de29