diff --git a/controllers/csaf_controller.go b/controllers/csaf_controller.go index 5b25c632..e0ecd38b 100644 --- a/controllers/csaf_controller.go +++ b/controllers/csaf_controller.go @@ -245,7 +245,6 @@ func (controller *CSAFController) GetReportsByYearHTML(ctx shared.Context) error // extract the requested year and build the revision history first year := strings.TrimRight(ctx.Param("year"), "/") allVulns, err := controller.dependencyVulnRepository.GetAllVulnsByAssetID(nil, asset.ID) - if err != nil { return err } @@ -257,6 +256,12 @@ func (controller *CSAFController) GetReportsByYearHTML(ctx shared.Context) error vulnsOfThatYear := utils.Filter(allVulns, func(vuln models.DependencyVuln) bool { return len(vuln.Events) > 0 && vuln.Events[0].CreatedAt.Year() == yearNumber }) + + // deduplicate Slice to avoid listing the same CVEs + vulnsOfThatYear = utils.DeduplicateSlice(vulnsOfThatYear, func(vuln models.DependencyVuln) string { + return vuln.CVEID + }) + type pageData struct { Year int Filenames []string diff --git a/database/repositories/dependency_vuln_repository.go b/database/repositories/dependency_vuln_repository.go index 295bcfac..f96b966f 100644 --- a/database/repositories/dependency_vuln_repository.go +++ b/database/repositories/dependency_vuln_repository.go @@ -195,6 +195,10 @@ func (repository *dependencyVulnRepository) GetByAssetVersionPaged(tx *gorm.DB, packageNameQuery = packageNameQuery.Where(f.SQL(), f.Value()) } + if search != "" && len(search) > 2 { + packageNameQuery.Where("(\"CVE\".description ILIKE ? OR dependency_vulns.cve_id ILIKE ? OR component_purl ILIKE ?)", "%"+search+"%", "%"+search+"%", "%"+search+"%") + } + // apply sorting if len(sort) > 0 { for _, s := range sort { diff --git a/utils/common.go b/utils/common.go index 6ae9c30a..92c3b254 100644 --- a/utils/common.go +++ b/utils/common.go @@ -158,3 +158,18 @@ func GetDirFromPath(path string) string { } return path } + +// DeduplicateSlice deduplicates a slice in O(n) out of place. +func DeduplicateSlice[T any](slice []T, idFunc func(t T) string) []T { + deduplicatedSlice := make([]T, 0, len(slice)) + seen := make(map[string]struct{}, len(slice)) + for i := range slice { + id := idFunc(slice[i]) + if _, ok := seen[id]; ok { + continue + } + seen[id] = struct{}{} + deduplicatedSlice = append(deduplicatedSlice, slice[i]) + } + return deduplicatedSlice +}