diff --git a/vmaas/cves.go b/vmaas/cves.go index 3fdff05..98adc90 100644 --- a/vmaas/cves.go +++ b/vmaas/cves.go @@ -18,9 +18,12 @@ type Cves struct { func (req *CvesRequest) getSortedCves(c *Cache) ([]string, error) { cves := req.Cves if len(cves) == 0 { - return nil, errors.New("cve_list must contain at least one item") + return nil, errors.Wrap(ErrProcessingInput, "cve_list must contain at least one item") + } + cves, err := utils.TryExpandRegexPattern(cves, c.CveDetail) + if err != nil { + return nil, errors.Wrap(ErrProcessingInput, "invalid regex pattern") } - cves = utils.TryExpandRegexPattern(cves, c.CveDetail) slices.Sort(cves) return cves, nil } @@ -43,13 +46,13 @@ func filterInputCves(c *Cache, cves []string, req *CvesRequest) []string { continue } - if req.ModifiedSince != nil && cveDetail.ModifiedDate != nil { - if cveDetail.ModifiedDate.Before(*req.ModifiedSince) { + if req.ModifiedSince != nil { + if cveDetail.ModifiedDate == nil || cveDetail.ModifiedDate.Before(*req.ModifiedSince) { continue } } - if req.PublishedSince != nil && cveDetail.PublishedDate != nil { - if cveDetail.PublishedDate.Before(*req.PublishedSince) { + if req.PublishedSince != nil { + if cveDetail.PublishedDate == nil || cveDetail.PublishedDate.Before(*req.PublishedSince) { continue } } @@ -68,6 +71,9 @@ func (c *Cache) loadCveDetails(cves []string) CveDetails { binPackages, sourcePackages := c.packageIDs2Nevras(cveDetail.PkgIDs) cveDetail.Packages = binPackages cveDetail.SourcePackages = sourcePackages + if cveDetail.CWEs == nil { + cveDetail.CWEs = []string{} + } cveDetails[cve] = cveDetail } return cveDetails @@ -76,7 +82,7 @@ func (c *Cache) loadCveDetails(cves []string) CveDetails { func (req *CvesRequest) cves(c *Cache) (*Cves, error) { // TODO: implement opts cves, err := req.getSortedCves(c) if err != nil { - return nil, err + return &Cves{}, err } cves = filterInputCves(c, cves, req) diff --git a/vmaas/cves_test.go b/vmaas/cves_test.go index 34373e7..704d1be 100644 --- a/vmaas/cves_test.go +++ b/vmaas/cves_test.go @@ -46,14 +46,12 @@ func TestFilterInputCves(t *testing.T) { testTime, _ := time.Parse(time.RFC3339, "2024-10-03T15:01:01Z") req = &CvesRequest{ModifiedSince: &testTime} filteredIDs = filterInputCves(c, cves, req) - assert.Equal(t, 1, len(filteredIDs)) - assert.Equal(t, "CVE-2024-1234", filteredIDs[0]) + assert.Equal(t, 0, len(filteredIDs)) // With published date before req.PublishedSince req = &CvesRequest{PublishedSince: &testTime} filteredIDs = filterInputCves(c, cves, req) - assert.Equal(t, 1, len(filteredIDs)) - assert.Equal(t, "CVE-2024-1234", filteredIDs[0]) + assert.Equal(t, 0, len(filteredIDs)) } func TestLoadCveDetails(t *testing.T) { diff --git a/vmaas/errata.go b/vmaas/errata.go index 974a366..d8a73ea 100644 --- a/vmaas/errata.go +++ b/vmaas/errata.go @@ -21,7 +21,10 @@ func (req *ErrataRequest) getSortedErrata(c *Cache) ([]string, error) { if len(req.Errata) == 0 { return nil, errors.New("errata_list must contain at least one item") } - errata := utils.TryExpandRegexPattern(req.Errata, c.ErratumDetails) + errata, err := utils.TryExpandRegexPattern(req.Errata, c.ErratumDetails) + if err != nil { + return nil, errors.Wrap(ErrProcessingInput, "invalid regex pattern") + } slices.Sort(errata) return errata, nil } diff --git a/vmaas/utils/expand_regex.go b/vmaas/utils/expand_regex.go index 3e30e22..b5c0be4 100644 --- a/vmaas/utils/expand_regex.go +++ b/vmaas/utils/expand_regex.go @@ -7,12 +7,20 @@ import ( // 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 { +func TryExpandRegexPattern[T any](inLabels []string, dataByLabels map[string]T) ([]string, error) { if len(inLabels) != 1 { - return inLabels + return inLabels, nil } pattern := inLabels[0] + + // Check pattern before adding ^ and $. + // For example, go implementation errors out on `*`, but doesn't on `^*$`. + _, err := regexp.Compile(pattern) + if err != nil { + return nil, err + } + if !strings.HasPrefix(pattern, "^") { pattern = "^" + pattern } @@ -20,10 +28,7 @@ func TryExpandRegexPattern[T any](inLabels []string, dataByLabels map[string]T) pattern += "$" } - re, err := regexp.Compile(pattern) - if err != nil { - return inLabels - } + re := regexp.MustCompile(pattern) outLabels := make([]string, 0, len(dataByLabels)) for label := range dataByLabels { @@ -32,5 +37,5 @@ func TryExpandRegexPattern[T any](inLabels []string, dataByLabels map[string]T) outLabels = append(outLabels, label) } } - return outLabels + return outLabels, nil } diff --git a/vmaas/utils/expand_regex_test.go b/vmaas/utils/expand_regex_test.go index 1c79f66..10fc7c1 100644 --- a/vmaas/utils/expand_regex_test.go +++ b/vmaas/utils/expand_regex_test.go @@ -16,18 +16,22 @@ func TestTryExpandRegexPattern(t *testing.T) { } // empty slice - outLabels := TryExpandRegexPattern([]string{}, labelDetails) + 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) + outLabels, _ = TryExpandRegexPattern(inLabels[0:1], labelDetails) assert.Equal(t, inLabels[0], outLabels[0]) // more labels in inLabels - outLabels = TryExpandRegexPattern(inLabels, labelDetails) + outLabels, _ = TryExpandRegexPattern(inLabels, labelDetails) assert.Equal(t, len(inLabels), len(outLabels)) // with regex - outLabels = TryExpandRegexPattern(regexLabel, labelDetails) + outLabels, _ = TryExpandRegexPattern(regexLabel, labelDetails) assert.Equal(t, 2, len(outLabels)) + + // invalid regex + _, err := TryExpandRegexPattern([]string{"*"}, labelDetails) + assert.Error(t, err) }