Skip to content

Commit

Permalink
sort order for matches should consider fix info (#1933)
Browse files Browse the repository at this point in the history
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
  • Loading branch information
wagoodman committed Jun 12, 2024
1 parent 9d28137 commit 97edf42
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 5 deletions.
46 changes: 44 additions & 2 deletions grype/match/matches_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,56 @@ func TestMatchesSortMixedDimensions(t *testing.T) {
Type: syftPkg.RpmPkg,
},
}
sixth := Match{
Vulnerability: vulnerability.Vulnerability{
ID: "CVE-2020-0020",
Fix: vulnerability.Fix{
Versions: []string{"2.0.0", "1.0.0"},
},
},
Package: pkg.Package{
ID: pkg.ID(uuid.NewString()),
Name: "package-d",
Version: "2.0.0",
Type: syftPkg.RpmPkg,
},
}
seventh := Match{
Vulnerability: vulnerability.Vulnerability{
ID: "CVE-2020-0020",
Fix: vulnerability.Fix{
Versions: []string{"2.0.1"},
},
},
Package: pkg.Package{
ID: pkg.ID(uuid.NewString()),
Name: "package-d",
Version: "2.0.0",
Type: syftPkg.RpmPkg,
},
}
eighth := Match{
Vulnerability: vulnerability.Vulnerability{
ID: "CVE-2020-0020",
Fix: vulnerability.Fix{
Versions: []string{"3.0.0"},
},
},
Package: pkg.Package{
ID: pkg.ID(uuid.NewString()),
Name: "package-d",
Version: "2.0.0",
Type: syftPkg.RpmPkg,
},
}

input := []Match{
// shuffle vulnerability id, package name, package version, and package type
fifth, third, first, second, fourth,
fifth, eighth, third, seventh, first, sixth, second, fourth,
}
matches := NewMatches(input...)

assertMatchOrder(t, []Match{first, second, third, fourth, fifth}, matches.Sorted())
assertMatchOrder(t, []Match{first, second, third, fourth, fifth, sixth, seventh, eighth}, matches.Sorted())

}

Expand Down
16 changes: 15 additions & 1 deletion grype/match/sort.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package match

import "sort"
import (
"sort"
"strings"
)

var _ sort.Interface = (*ByElements)(nil)

Expand All @@ -16,6 +19,17 @@ func (m ByElements) Less(i, j int) bool {
if m[i].Vulnerability.ID == m[j].Vulnerability.ID {
if m[i].Package.Name == m[j].Package.Name {
if m[i].Package.Version == m[j].Package.Version {
if m[i].Package.Type == m[j].Package.Type {
// this is an approximate ordering, but is not accurate in terms of semver and other version formats
// but stability is what is important here, not the accuracy of the sort.
fixVersions1 := m[i].Vulnerability.Fix.Versions
fixVersions2 := m[j].Vulnerability.Fix.Versions
sort.Strings(fixVersions1)
sort.Strings(fixVersions2)
fixStr1 := strings.Join(fixVersions1, ",")
fixStr2 := strings.Join(fixVersions2, ",")
return fixStr1 < fixStr2
}
return m[i].Package.Type < m[j].Package.Type
}
return m[i].Package.Version < m[j].Package.Version
Expand Down
4 changes: 4 additions & 0 deletions grype/presenter/table/presenter.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ func sortRows(rows [][]string) [][]string {
var (
name = 0
ver = 1
fix = 2
packageType = 3
vuln = 4
sev = 5
Expand All @@ -134,6 +135,9 @@ func sortRows(rows [][]string) [][]string {
if rows[i][ver] == rows[j][ver] {
if rows[i][packageType] == rows[j][packageType] {
if models.SeverityScore(rows[i][sev]) == models.SeverityScore(rows[j][sev]) {
if rows[i][vuln] == rows[j][vuln] {
return rows[i][fix] < rows[j][fix]
}
// we use > here to get the most recently filed vulnerabilities
// to show at the top of the severity
return rows[i][vuln] > rows[j][vuln]
Expand Down
6 changes: 4 additions & 2 deletions grype/presenter/table/presenter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ func TestSortRows(t *testing.T) {
{"a", "v0.1.0", "", "deb", "CVE-2018-9996", "Critical"},
{"a", "v0.2.0", "", "deb", "CVE-2010-9996", "High"},
{"b", "v0.2.0", "", "deb", "CVE-2010-9996", "Medium"},
{"b", "v0.2.0", "", "deb", "CVE-2019-9996", "High"},
{"b", "v0.2.0", "2.0.0", "deb", "CVE-2019-9996", "High"},
{"b", "v0.2.0", "1.0.0", "deb", "CVE-2019-9996", "High"},
{"d", "v0.4.0", "", "node", "CVE-2011-9996", "Low"},
{"d", "v0.4.0", "", "node", "CVE-2012-9996", "Negligible"},
{"c", "v0.6.0", "", "node", "CVE-2013-9996", "Critical"},
Expand All @@ -174,7 +175,8 @@ func TestSortRows(t *testing.T) {
{"a", "v0.1.0", "", "deb", "CVE-2019-9996", "Critical"},
{"a", "v0.1.0", "", "deb", "CVE-2018-9996", "Critical"},
{"a", "v0.2.0", "", "deb", "CVE-2010-9996", "High"},
{"b", "v0.2.0", "", "deb", "CVE-2019-9996", "High"},
{"b", "v0.2.0", "1.0.0", "deb", "CVE-2019-9996", "High"},
{"b", "v0.2.0", "2.0.0", "deb", "CVE-2019-9996", "High"},
{"b", "v0.2.0", "", "deb", "CVE-2010-9996", "Medium"},
{"c", "v0.6.0", "", "node", "CVE-2013-9996", "Critical"},
{"d", "v0.4.0", "", "node", "CVE-2011-9996", "Low"},
Expand Down

0 comments on commit 97edf42

Please sign in to comment.