diff --git a/go.mod b/go.mod index e50ee72..6f3e4a1 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.15 require ( github.com/bitly/go-simplejson v0.5.0 github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect + github.com/dlclark/regexp2 v1.4.0 github.com/grafana/grafana-plugin-sdk-go v0.133.0 github.com/hashicorp/go-hclog v0.16.1 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible diff --git a/go.sum b/go.sum index f18f0fd..e75adf6 100644 --- a/go.sum +++ b/go.sum @@ -72,6 +72,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E= +github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/elazarl/goproxy v0.0.0-20220115173737-adb46da277ac/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= github.com/elazarl/goproxy/ext v0.0.0-20220115173737-adb46da277ac/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= diff --git a/pkg/zabbix/methods.go b/pkg/zabbix/methods.go index be31fed..7f8cb1d 100644 --- a/pkg/zabbix/methods.go +++ b/pkg/zabbix/methods.go @@ -148,7 +148,11 @@ func filterItemsByTag(items []*Item, filter string) ([]*Item, error) { } for _, t := range tags { if re != nil { - if re.MatchString(t) { + match, err := re.MatchString(t) + if err != nil { + return nil, err + } + if match { filteredItems = append(filteredItems, i) break } @@ -173,7 +177,11 @@ func filterItemsByQuery(items []*Item, filter string) ([]*Item, error) { for _, i := range items { name := i.Name if re != nil { - if re.MatchString(name) { + match, err := re.MatchString(name) + if err != nil { + return nil, err + } + if match { filteredItems = append(filteredItems, i) } } else if name == filter { @@ -212,7 +220,11 @@ func filterAppsByQuery(items []Application, filter string) ([]Application, error for _, i := range items { name := i.Name if re != nil { - if re.MatchString(name) { + match, err := re.MatchString(name) + if err != nil { + return nil, err + } + if match { filteredItems = append(filteredItems, i) } } else if name == filter { @@ -251,7 +263,11 @@ func filterHostsByQuery(items []Host, filter string) ([]Host, error) { for _, i := range items { name := i.Name if re != nil { - if re.MatchString(name) { + match, err := re.MatchString(name) + if err != nil { + return nil, err + } + if match { filteredItems = append(filteredItems, i) } } else if name == filter { @@ -282,7 +298,11 @@ func filterGroupsByQuery(items []Group, filter string) ([]Group, error) { for _, i := range items { name := i.Name if re != nil { - if re.MatchString(name) { + match, err := re.MatchString(name) + if err != nil { + return nil, err + } + if match { filteredItems = append(filteredItems, i) } } else if name == filter { diff --git a/pkg/zabbix/utils.go b/pkg/zabbix/utils.go index 2c96282..e772f2d 100644 --- a/pkg/zabbix/utils.go +++ b/pkg/zabbix/utils.go @@ -4,6 +4,8 @@ import ( "fmt" "regexp" "strings" + + "github.com/dlclark/regexp2" ) func (item *Item) ExpandItemName() string { @@ -63,9 +65,10 @@ func splitKeyParams(paramStr string) []string { return params } -func parseFilter(filter string) (*regexp.Regexp, error) { - regex := regexp.MustCompile(`^/(.+)/([imsU]*)$`) - flagRE := regexp.MustCompile("[imsU]+") +func parseFilter(filter string) (*regexp2.Regexp, error) { + vaildREModifiers := "imncsxrde" + regex := regexp.MustCompile(`^/(.+)/([imncsxrde]*)$`) + flagRE := regexp.MustCompile(fmt.Sprintf("[%s]+", vaildREModifiers)) matches := regex.FindStringSubmatch(filter) if len(matches) <= 1 { @@ -77,12 +80,12 @@ func parseFilter(filter string) (*regexp.Regexp, error) { if flagRE.MatchString(matches[2]) { pattern += "(?" + matches[2] + ")" } else { - return nil, fmt.Errorf("error parsing regexp: unsupported flags `%s` (expected [imsU])", matches[2]) + return nil, fmt.Errorf("error parsing regexp: unsupported flags `%s` (expected [%s])", matches[2], vaildREModifiers) } } pattern += matches[1] - return regexp.Compile(pattern) + return regexp2.Compile(pattern, regexp2.RE2) } func itemTagToString(tag ItemTag) string { diff --git a/pkg/zabbix/utils_test.go b/pkg/zabbix/utils_test.go index 911154a..d750a13 100644 --- a/pkg/zabbix/utils_test.go +++ b/pkg/zabbix/utils_test.go @@ -1,8 +1,10 @@ package zabbix import ( + "reflect" "testing" + "github.com/dlclark/regexp2" "github.com/stretchr/testify/assert" ) @@ -61,26 +63,43 @@ func TestParseFilter(t *testing.T) { tests := []struct { name string filter string + want *regexp2.Regexp expectNoError bool expectedError string }{ { name: "Simple regexp", filter: "/.*/", + want: regexp2.MustCompile(".*", regexp2.RE2), expectNoError: true, expectedError: "", }, { name: "Not a regex", filter: "/var/lib/mysql: Total space", + want: nil, expectNoError: true, expectedError: "", }, + { + name: "Regexp with modifier", + filter: "/.*/i", + want: regexp2.MustCompile("(?i).*", regexp2.RE2), + expectNoError: true, + expectedError: "", + }, + { + name: "Regexp with unsupported modifier", + filter: "/.*/1", + want: nil, + expectNoError: false, + expectedError: "", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - _, err := parseFilter(tt.filter) + got, err := parseFilter(tt.filter) if tt.expectNoError { assert.NoError(t, err) } @@ -88,6 +107,9 @@ func TestParseFilter(t *testing.T) { assert.Error(t, err) assert.EqualError(t, err, tt.expectedError) } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("parseFilter() = %v, want %v", got, tt.want) + } }) } }