From 7042f2e5428f2c80435bffdd56b3694c5fd0fe8a Mon Sep 17 00:00:00 2001 From: Norway-02 Date: Thu, 10 Sep 2026 12:04:42 +0530 Subject: [PATCH] fix(pkg/filematcher): escape regex special characters in pattern matcher Signed-off-by: Norway-02 --- pkg/filematcher/filematcher.go | 27 +++++++++++++++++++++++---- pkg/filematcher/filematcher_test.go | 5 +++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/pkg/filematcher/filematcher.go b/pkg/filematcher/filematcher.go index 8a9ef53174..4402841ffc 100644 --- a/pkg/filematcher/filematcher.go +++ b/pkg/filematcher/filematcher.go @@ -181,11 +181,23 @@ func (p *Pattern) regexpString() string { escSL += `\` } + inClass := false + for scan.Peek() != scanner.EOF { ch := scan.Next() switch ch { + case '[': + inClass = true + regStr += string(ch) + case ']': + inClass = false + regStr += string(ch) case '*': + if inClass { + regStr += string(ch) + continue + } if scan.Peek() == '*' { // Is some flavor of "**". scan.Next() @@ -209,12 +221,19 @@ func (p *Pattern) regexpString() string { regStr += "[^" + escSL + "]*" } case '?': + if inClass { + regStr += string(ch) + continue + } // "?" is any char except "/". regStr += "[^" + escSL + "]" - case '.', '$': - // Escape some regexp special chars that have no meaning - // in golang's filepath.Match. - regStr += `\` + string(ch) + case '.', '$', '+', '(', ')', '{', '}', '|', '^': + if inClass { + regStr += string(ch) + } else { + // Escape regexp special chars that have no meaning in filepath.Match. + regStr += `\` + string(ch) + } case '\\': // Escape next char. Note that a trailing \ in the pattern // will be left alone (but need to escape it). diff --git a/pkg/filematcher/filematcher_test.go b/pkg/filematcher/filematcher_test.go index 44500a4bd1..f6f9822f45 100644 --- a/pkg/filematcher/filematcher_test.go +++ b/pkg/filematcher/filematcher_test.go @@ -172,6 +172,11 @@ func TestMatches(t *testing.T) { {"abc/**", "abc/def/ghi", true}, {"**/.foo", ".foo", true}, {"**/.foo", "bar.foo", false}, + {"a+b.txt", "a+b.txt", true}, + {"foo(1).txt", "foo(1).txt", true}, + {"foo{1}.txt", "foo{1}.txt", true}, + {"foo|bar.txt", "foo|bar.txt", true}, + {"^foo.txt", "^foo.txt", true}, } for _, test := range tests {