From 90f8d1b6756825093f92547f6141bd196c5a3a80 Mon Sep 17 00:00:00 2001 From: Aaron Lehmann Date: Mon, 26 Jul 2021 11:28:10 -0700 Subject: [PATCH] fileutils: Fix incorrect handling of "**/foo" pattern (*PatternMatcher).Matches includes a special case for when the pattern matches a parent dir, even though it doesn't match the current path. However, it assumes that the parent dir which would match the pattern must have the same number of separators as the pattern itself. This doesn't hold true with a patern like "**/foo". A file foo/bar would have len(parentPathDirs) == 1, which is less than the number of path len(pattern.dirs) == 2... therefore this check would be skipped. Given that "**/foo" matches "foo", I think it's a bug that the "parent subdir matches" check is being skipped in this case. It seems safer to loop over the parent subdirs and check each against the pattern. It's possible there is a safe optimization to check only a certain subset, but the existing logic seems unsafe. Signed-off-by: Aaron Lehmann --- pkg/fileutils/fileutils.go | 7 +++++-- pkg/fileutils/fileutils_test.go | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pkg/fileutils/fileutils.go b/pkg/fileutils/fileutils.go index fd4fb7f08f..31c5f78ec6 100644 --- a/pkg/fileutils/fileutils.go +++ b/pkg/fileutils/fileutils.go @@ -77,8 +77,11 @@ func (pm *PatternMatcher) Matches(file string) (bool, error) { if !match && parentPath != "." { // Check to see if the pattern matches one of our parent dirs. - if len(pattern.dirs) <= len(parentPathDirs) { - match, _ = pattern.match(strings.Join(parentPathDirs[:len(pattern.dirs)], string(os.PathSeparator))) + for i := range parentPathDirs { + match, _ = pattern.match(strings.Join(parentPathDirs[:i+1], string(os.PathSeparator))) + if match { + break + } } } diff --git a/pkg/fileutils/fileutils_test.go b/pkg/fileutils/fileutils_test.go index 36064b6f5f..e11711b653 100644 --- a/pkg/fileutils/fileutils_test.go +++ b/pkg/fileutils/fileutils_test.go @@ -328,6 +328,8 @@ func TestMatches(t *testing.T) { {"dir/**", "dir/file/", true}, {"dir/**", "dir/dir2/file", true}, {"dir/**", "dir/dir2/file/", true}, + {"**/dir", "dir", true}, + {"**/dir", "dir/file", true}, {"**/dir2/*", "dir/dir2/file", true}, {"**/dir2/*", "dir/dir2/file/", true}, {"**/dir2/**", "dir/dir2/dir3/file", true},