From c27cb7af08172ac30913cd13d9cae11378020353 Mon Sep 17 00:00:00 2001 From: TwinProduction Date: Mon, 4 Jan 2021 18:01:39 -0500 Subject: [PATCH] Fix issue with backslashes when using pattern function --- pattern/pattern.go | 9 ++++++++- pattern/pattern_bench_test.go | 21 +++++++++++++++++++++ pattern/pattern_test.go | 26 ++++++++++++++++---------- 3 files changed, 45 insertions(+), 11 deletions(-) create mode 100644 pattern/pattern_bench_test.go diff --git a/pattern/pattern.go b/pattern/pattern.go index 44f02022..1eaef3b1 100644 --- a/pattern/pattern.go +++ b/pattern/pattern.go @@ -1,12 +1,19 @@ package pattern -import "path/filepath" +import ( + "path/filepath" + "strings" +) // Match checks whether a string matches a pattern func Match(pattern, s string) bool { if pattern == "*" { return true } + // Backslashes break filepath.Match, so we'll remove all of them. + // This has a pretty significant impact on performance when there + // are backslashes, but at least it doesn't break filepath.Match. + s = strings.ReplaceAll(s, "\\", "") matched, _ := filepath.Match(pattern, s) return matched } diff --git a/pattern/pattern_bench_test.go b/pattern/pattern_bench_test.go new file mode 100644 index 00000000..e27df78f --- /dev/null +++ b/pattern/pattern_bench_test.go @@ -0,0 +1,21 @@ +package pattern + +import "testing" + +func BenchmarkMatch(b *testing.B) { + for n := 0; n < b.N; n++ { + if !Match("*ing*", "livingroom") { + b.Error("should've matched") + } + } + b.ReportAllocs() +} + +func BenchmarkMatchWithBackslash(b *testing.B) { + for n := 0; n < b.N; n++ { + if !Match("*ing*", "living\\room") { + b.Error("should've matched") + } + } + b.ReportAllocs() +} diff --git a/pattern/pattern_test.go b/pattern/pattern_test.go index 6b56522e..c4b84f9b 100644 --- a/pattern/pattern_test.go +++ b/pattern/pattern_test.go @@ -1,6 +1,9 @@ package pattern -import "testing" +import ( + "fmt" + "testing" +) func TestMatch(t *testing.T) { testMatch(t, "*", "livingroom_123", true) @@ -15,6 +18,7 @@ func TestMatch(t *testing.T) { testMatch(t, "*vin*om*2*", "livingroom_123", true) testMatch(t, "livingroom_123", "livingroom_123", true) testMatch(t, "*livingroom_123*", "livingroom_123", true) + testMatch(t, "*test*", "\\test", true) testMatch(t, "livingroom", "livingroom_123", false) testMatch(t, "livingroom123", "livingroom_123", false) testMatch(t, "what", "livingroom_123", false) @@ -24,14 +28,16 @@ func TestMatch(t *testing.T) { } func testMatch(t *testing.T, pattern, key string, expectedToMatch bool) { - matched := Match(pattern, key) - if expectedToMatch { - if !matched { - t.Errorf("%s should've matched pattern '%s'", key, pattern) + t.Run(fmt.Sprintf("pattern '%s' from '%s'", pattern, key), func(t *testing.T) { + matched := Match(pattern, key) + if expectedToMatch { + if !matched { + t.Errorf("%s should've matched pattern '%s'", key, pattern) + } + } else { + if matched { + t.Errorf("%s shouldn't have matched pattern '%s'", key, pattern) + } } - } else { - if matched { - t.Errorf("%s shouldn't have matched pattern '%s'", key, pattern) - } - } + }) }