From 8cd7d67cee3b2087b7cf4d3df8a23cd7d9f1713f Mon Sep 17 00:00:00 2001 From: ze0s <43699394+zze0s@users.noreply.github.com> Date: Wed, 23 Oct 2024 16:33:49 +0200 Subject: [PATCH] fix(wildcard): match on multi-line data (#1780) * fix(wildcard): match on multi-line data * fix(wildcard): remove duplicate block --- pkg/wildcard/match.go | 26 +++++++++++++------------- pkg/wildcard/match_test.go | 24 ++++++++++++++++-------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/pkg/wildcard/match.go b/pkg/wildcard/match.go index 94fe998..b0b4acf 100644 --- a/pkg/wildcard/match.go +++ b/pkg/wildcard/match.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/autobrr/autobrr/pkg/regexcache" + "github.com/rs/zerolog/log" ) @@ -29,22 +30,26 @@ func Match(pattern, name string) (matched bool) { func match(pattern, name string, simple bool) (matched bool) { if pattern == "" { // return name == "" + } else if pattern == "*" { // * return true + } else if !simple && pattern == "?" { // ? return len(name) == 1 + } else if idx := strings.IndexAny(pattern, "*?"); idx == -1 || (simple && pattern[idx] == '?' && !strings.Contains(pattern, "*")) { // egg return name == pattern + } else if idx == len(pattern)-1 && pattern[idx] == '*' { // egg* return strings.HasPrefix(name, pattern[:idx-1]) - } else if wildEnd := pattern[len(pattern)-1] == '*'; !simple && - ((wildEnd && strings.Count(pattern, "*") == 1) || // egg?bert* - (len(pattern) == len(name) && !strings.Contains(pattern, "*"))) { // egg?bert? + // egg?bert* + } else if wildEnd := pattern[len(pattern)-1] == '*'; !simple && ((wildEnd && strings.Count(pattern, "*") == 1) || (len(pattern) == len(name) && !strings.Contains(pattern, "*"))) { // egg?bert? return matchComplex(name, pattern, wildEnd) - } else if strings.HasPrefix(pattern, "*") && strings.HasSuffix(pattern, "*") && // *egg* - (simple || (!simple && !strings.Contains(pattern, "?"))) && // simple is fine, if not we need to check for ? and skip if so. - strings.Count(pattern, "*") == 2 { // make sure that we have no other wildcards. + + // *egg* + // simple is fine, if not we need to check for ? and skip if so. + } else if strings.HasPrefix(pattern, "*") && strings.HasSuffix(pattern, "*") && (simple || (!simple && !strings.Contains(pattern, "?"))) && strings.Count(pattern, "*") == 2 { // make sure that we have no other wildcards. return strings.Contains(name, pattern[1:len(pattern)-1]) } @@ -146,7 +151,7 @@ func cleanForRegex(pattern string, simple bool) string { } func prepForRegex(pattern string) string { - return `^` + regexp.QuoteMeta(pattern) + `$` + return `(?m)^` + regexp.QuoteMeta(pattern) + `$` } func deepMatchRune(str, pattern string, simple bool, original string, bulk bool) bool { @@ -174,10 +179,5 @@ func deepMatchRune(str, pattern string, simple bool, original string, bulk bool) regexcache.SubmitOriginal(original+salt, user) } - idx := user.FindStringIndex(str) - if idx == nil { - return false - } - - return idx[1] == len(str) + return user.MatchString(str) } diff --git a/pkg/wildcard/match_test.go b/pkg/wildcard/match_test.go index a1fa2ae..7947856 100644 --- a/pkg/wildcard/match_test.go +++ b/pkg/wildcard/match_test.go @@ -4,7 +4,10 @@ package wildcard import ( + "fmt" "testing" + + "github.com/stretchr/testify/assert" ) // TestMatch - Tests validate the logic of wild card matching. @@ -12,7 +15,7 @@ import ( // A '*' in a provided string will not result in matching the strings before and after the '*' of the string provided. // Sample usage: In resource matching for bucket policy validation. func TestMatch(t *testing.T) { - testCases := []struct { + tests := []struct { pattern string text string matched bool @@ -69,7 +72,7 @@ func TestMatch(t *testing.T) { }, { pattern: "*EP?B*", - text: "Translated (Group) / EPUB", + text: "ARG THIS IS A STUPID LONG ONG LONG LONG STRING BEFORE AND AFTER \\n ARG THIS IS A STUPID LONG ONG LONG LONG STRING BEFORE AND AFTER \\n ARG THIS IS A STUPID LONG ONG LONG LONG STRING BEFORE AND AFTER \\n ARG THIS IS A STUPID LONG ONG LONG LONG STRING BEFORE AND AFTER \\n Translated (Group) / EPUB WITH OTHER STUFF ON THE OTHER END ARG THIS IS A STUPID LONG ONG LONG LONG STRING BEFORE AND AFTER \\n ARG THIS IS A STUPID LONG ONG LONG LONG STRING BEFORE AND AFTER \\n ARG THIS IS A STUPID LONG ONG LONG LONG STRING BEFORE AND AFTER \\n ", matched: true, }, { @@ -127,13 +130,18 @@ func TestMatch(t *testing.T) { text: "T?Q", matched: true, }, + { + pattern: "*black?metal*", + text: " || Artist......: Vredehammer ||\n || Album.......: Mintaka ||\n || Year........: 2013 ||\n || ||\n || Genre.......: black metal ||\n || Label.......: Indie Recordings ||\n || ||\n || Source......: FLAC/WEB (16bit) ||\n || Encoder.....: libFLAC ||\n || Bitrate.....: 948 kbps avg. ||\n || F.Rate......: 44.1kHz ||\n || ||\n || Playtime....: 00:19:27 / 138.70MB ||\n || R.Date......: 2024-10-22 ||\n || S.Date......: 2013-03-27 ||\n || ||\n || ||\n || 01. The King Has Risen 3:53 ||\n || 02. H├╕ster av sjeler 4:17 ||\n || 03. Mintaka 4:10 ||\n || 04. Ditt siste aandedrag 7:07 ||\n || ||\n || ||\n || Vredehammer combines aggressive guitars and Norse melodies. ||\n ", + matched: true, + }, } - // Iterating over the test cases, call the function under test and assert the output. - for i, testCase := range testCases { - actualResult := Match(testCase.pattern, testCase.text) - if testCase.matched != actualResult { - t.Errorf("Test %d: Expected the result to be `%v`, but instead found it to be `%v`", i+1, testCase.matched, actualResult) - } + for idx, tt := range tests { + t.Run(fmt.Sprintf("match: %d", idx), func(t *testing.T) { + actualResult := Match(tt.pattern, tt.text) + assert.Equal(t, tt.matched, actualResult) + + }) } }