diff --git a/vmaas/cves.go b/vmaas/cves.go index 99c546c..0e25771 100644 --- a/vmaas/cves.go +++ b/vmaas/cves.go @@ -58,7 +58,7 @@ func (req *CvesRequest) getSortedCves(c *Cache) ([]string, error) { if len(cves) == 0 { return nil, errors.New("cve_list must contain at least one item") } - // TODO: implement expanding by regex + cves = utils.TryExpandRegexPattern(cves, c.CveDetail) slices.Sort(cves) return cves, nil } diff --git a/vmaas/utils/expand_regex.go b/vmaas/utils/expand_regex.go new file mode 100644 index 0000000..3e30e22 --- /dev/null +++ b/vmaas/utils/expand_regex.go @@ -0,0 +1,36 @@ +package utils + +import ( + "regexp" + "strings" +) + +// TryExpandRegexPattern treats the item in a single-label slice like a regex pattern +// and returns all matching labels from dataByLabels, otherwise it returns inLabels. +func TryExpandRegexPattern[T any](inLabels []string, dataByLabels map[string]T) []string { + if len(inLabels) != 1 { + return inLabels + } + + pattern := inLabels[0] + if !strings.HasPrefix(pattern, "^") { + pattern = "^" + pattern + } + if !strings.HasSuffix(pattern, "$") { + pattern += "$" + } + + re, err := regexp.Compile(pattern) + if err != nil { + return inLabels + } + + outLabels := make([]string, 0, len(dataByLabels)) + for label := range dataByLabels { + matched := re.Match([]byte(label)) + if matched { + outLabels = append(outLabels, label) + } + } + return outLabels +} diff --git a/vmaas/utils/expand_regex_test.go b/vmaas/utils/expand_regex_test.go new file mode 100644 index 0000000..1c79f66 --- /dev/null +++ b/vmaas/utils/expand_regex_test.go @@ -0,0 +1,33 @@ +package utils + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestTryExpandRegexPattern(t *testing.T) { + regexLabel := []string{`CVE-2024-1\d+`} + inLabels := []string{"CVE-2024-1234", "CVE-2024-21345"} + labelDetails := map[string]int{ + "CVE-2024-1234": 0, + "CVE-2024-12345": 0, + "CVE-2024-21345": 0, + } + + // empty slice + outLabels := TryExpandRegexPattern([]string{}, labelDetails) + assert.Equal(t, 0, len(outLabels)) + + // with a single lable that is not a regex pattern + outLabels = TryExpandRegexPattern(inLabels[0:1], labelDetails) + assert.Equal(t, inLabels[0], outLabels[0]) + + // more labels in inLabels + outLabels = TryExpandRegexPattern(inLabels, labelDetails) + assert.Equal(t, len(inLabels), len(outLabels)) + + // with regex + outLabels = TryExpandRegexPattern(regexLabel, labelDetails) + assert.Equal(t, 2, len(outLabels)) +}