fix(wildcard): partial match ignoring consumed pattern (#1765)

* tests(wildcard): ?

* really?

* Franklin

* remember when regex was easy

* ==

* why not.

* I need an adult.

* Update match_test.go

* tests + readability

* back to basics
This commit is contained in:
Kyle Sanderson 2024-10-20 04:03:52 -07:00 committed by GitHub
parent 2386a9db31
commit 5df6e78d3b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 52 additions and 22 deletions

View file

@ -41,8 +41,21 @@ func match(pattern, name string, simple bool) (matched bool) {
((wildEnd && strings.Count(pattern, "*") == 1) || // egg?bert* ((wildEnd && strings.Count(pattern, "*") == 1) || // egg?bert*
(len(pattern) == len(name) && !strings.Contains(pattern, "*"))) { // egg?bert? (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.
return strings.Contains(name, pattern[1:len(pattern)-1])
}
return deepMatchRune(name, pattern, simple, pattern, false)
}
func matchComplex(name, pattern string, wildEnd bool) bool {
base := 0 base := 0
for base < len(name) { consumedPattern := 0
for base < len(name) && consumedPattern < len(pattern) {
i := strings.IndexRune(pattern[base:], '?') i := strings.IndexRune(pattern[base:], '?')
if i == -1 { if i == -1 {
if (wildEnd && !strings.HasPrefix(name[base:], pattern[base:len(pattern)-1])) || // egg* if (wildEnd && !strings.HasPrefix(name[base:], pattern[base:len(pattern)-1])) || // egg*
@ -51,6 +64,7 @@ func match(pattern, name string, simple bool) (matched bool) {
} }
base = len(name) base = len(name)
consumedPattern = len(pattern)
continue continue
} }
@ -60,16 +74,10 @@ func match(pattern, name string, simple bool) (matched bool) {
} }
base = offset + 1 base = offset + 1
consumedPattern = base
} }
return base == len(name) return base == len(name) && consumedPattern == len(pattern)
} 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.
return strings.Contains(name, pattern[1:len(pattern)-1])
}
return deepMatchRune(name, pattern, simple, pattern, false)
} }
func MatchSliceSimple(pattern []string, name string) (matched bool) { func MatchSliceSimple(pattern []string, name string) (matched bool) {

View file

@ -107,6 +107,26 @@ func TestMatch(t *testing.T) {
text: "them", text: "them",
matched: false, matched: false,
}, },
{
pattern: "t?q*",
text: "tam e",
matched: false,
},
{
pattern: "Hard?Quiz*",
text: "HardX 24 10 12 Ella Reese XXX 1080p MP4-WRB",
matched: false,
},
{
pattern: "Hard?Quiz*",
text: "HardX",
matched: false,
},
{
pattern: "T?Q*",
text: "T?Q",
matched: true,
},
} }
// Iterating over the test cases, call the function under test and assert the output. // Iterating over the test cases, call the function under test and assert the output.
for i, testCase := range testCases { for i, testCase := range testCases {
@ -157,6 +177,7 @@ func TestMatchSliceSimple(t *testing.T) {
}{ }{
{[]string{"*", "test"}, "test", true}, {[]string{"*", "test"}, "test", true},
{[]string{"te?t", "tost", "random"}, "tost", true}, {[]string{"te?t", "tost", "random"}, "tost", true},
{[]string{"te?t", "t?s?", "random"}, "tost", false},
{[]string{"*st", "n?st", "l*st"}, "list", true}, {[]string{"*st", "n?st", "l*st"}, "list", true},
{[]string{"?", "?*", "?**"}, "t", false}, {[]string{"?", "?*", "?**"}, "t", false},
{[]string{"a", "b", "c"}, "d", false}, {[]string{"a", "b", "c"}, "d", false},
@ -182,6 +203,7 @@ func TestMatchSlice(t *testing.T) {
}{ }{
{[]string{"*", "test", "t?st"}, "test", true}, {[]string{"*", "test", "t?st"}, "test", true},
{[]string{"te?t", "t?st", "random"}, "tost", true}, {[]string{"te?t", "t?st", "random"}, "tost", true},
{[]string{"te?t", "t?s?", "random"}, "tost", true},
{[]string{"te?t", "t??e?", "random"}, "toser", true}, {[]string{"te?t", "t??e?", "random"}, "toser", true},
{[]string{"*st", "n?st", "l*st"}, "list", true}, {[]string{"*st", "n?st", "l*st"}, "list", true},
{[]string{"?", "??", "???"}, "t", true}, {[]string{"?", "??", "???"}, "t", true},