diff --git a/weed/util/wildcard/wildcard_matcher.go b/weed/util/wildcard/wildcard_matcher.go index 0d74ffe6c4..5b2b85f6da 100644 --- a/weed/util/wildcard/wildcard_matcher.go +++ b/weed/util/wildcard/wildcard_matcher.go @@ -155,13 +155,15 @@ func matchWildcardString(pattern, str string) bool { for targetIndex < len(str) { switch { - case patternIndex < len(pattern) && (pattern[patternIndex] == '?' || pattern[patternIndex] == str[targetIndex]): - targetIndex++ - patternIndex++ + // '*' must be checked before literal equality so a '*' in the target + // cannot consume the pattern wildcard without a backtrack point case patternIndex < len(pattern) && pattern[patternIndex] == '*': lastStarIndex = patternIndex lastStarMatchIndex = targetIndex patternIndex++ + case patternIndex < len(pattern) && (pattern[patternIndex] == '?' || pattern[patternIndex] == str[targetIndex]): + targetIndex++ + patternIndex++ case lastStarIndex != -1: patternIndex = lastStarIndex + 1 lastStarMatchIndex++ diff --git a/weed/util/wildcard/wildcard_matcher_test.go b/weed/util/wildcard/wildcard_matcher_test.go index 26f5f43a89..d318206a38 100644 --- a/weed/util/wildcard/wildcard_matcher_test.go +++ b/weed/util/wildcard/wildcard_matcher_test.go @@ -27,6 +27,12 @@ func TestMatchesWildcard(t *testing.T) { {"Pattern with regex special chars", "test[abc]", "test[abc]", true}, {"Pattern with dots", "test.txt", "test.txt", true}, {"Pattern with dots and wildcard", "*.txt", "test.txt", true}, + {"Star in target at pattern star offset", "a/*", "a/*b", true}, + {"Star in target equals pattern", "a/*", "a/*", true}, + {"Star in target past pattern star offset", "a/*", "a/x*y", true}, + {"Question mark matches literal star", "a/?c", "a/*c", true}, + {"Star in target is not a wildcard", "ab*", "a*b", false}, + {"ARN pattern with star in key", "arn:aws:s3:::bucket/finance/*", "arn:aws:s3:::bucket/finance/*star.txt", true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {