Skip to content

Commit

Permalink
Hide suppressed vulnerabilities when --show-suppressed is not given (#…
Browse files Browse the repository at this point in the history
…1322)

Signed-off-by: James Tran <jamestran201@github.com>
  • Loading branch information
jamestran201 committed May 30, 2023
1 parent 7c681d5 commit c1f6772
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 12 deletions.
71 changes: 71 additions & 0 deletions grype/presenter/models/models_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ func GenerateAnalysis(t *testing.T, scheme syftSource.Scheme) (match.Matches, []
return matches, packages, context, NewMetadataMock(), nil, nil
}

func GenerateAnalysisWithIgnoredMatches(t *testing.T, scheme syftSource.Scheme) (match.Matches, []match.IgnoredMatch, []pkg.Package, pkg.Context, vulnerability.MetadataProvider, interface{}, interface{}) {
t.Helper()

packages := generatePackages(t)
matches := generateMatches(t, packages[0], packages[0])
ignoredMatches := generateIgnoredMatches(t, packages[1])
context := generateContext(t, scheme)

return matches, ignoredMatches, packages, context, NewMetadataMock(), nil, nil
}

func SBOMFromPackages(t *testing.T, packages []pkg.Package) *sbom.SBOM {
t.Helper()

Expand Down Expand Up @@ -127,6 +138,66 @@ func generateMatches(t *testing.T, p, p2 pkg.Package) match.Matches {
return collection
}

func generateIgnoredMatches(t *testing.T, p pkg.Package) []match.IgnoredMatch {
t.Helper()

matches := []match.Match{
{

Vulnerability: vulnerability.Vulnerability{
ID: "CVE-1999-0001",
Namespace: "source-1",
},
Package: p,
Details: []match.Detail{
{
Type: match.ExactDirectMatch,
Matcher: match.DpkgMatcher,
SearchedBy: map[string]interface{}{
"distro": map[string]string{
"type": "ubuntu",
"version": "20.04",
},
},
Found: map[string]interface{}{
"constraint": ">= 20",
},
},
},
},
{

Vulnerability: vulnerability.Vulnerability{
ID: "CVE-1999-0002",
Namespace: "source-2",
},
Package: p,
Details: []match.Detail{
{
Type: match.ExactDirectMatch,
Matcher: match.DpkgMatcher,
SearchedBy: map[string]interface{}{
"cpe": "somecpe",
},
Found: map[string]interface{}{
"constraint": "somecpe",
},
},
},
},
}

var ignoredMatches []match.IgnoredMatch
for _, m := range matches {
ignoredMatches = append(ignoredMatches, match.IgnoredMatch{
Match: m,
AppliedIgnoreRules: []match.IgnoreRule{},
})
}

return ignoredMatches
}

func generatePackages(t *testing.T) []pkg.Package {
t.Helper()
epoch := 2
Expand Down
5 changes: 1 addition & 4 deletions grype/presenter/presenter.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ func GetPresenter(c Config, pb models.PresenterConfig) Presenter {
case jsonFormat:
return json.NewPresenter(pb)
case tableFormat:
if c.showSuppressed {
return table.NewPresenter(pb)
}
return table.NewPresenter(pb)
return table.NewPresenter(pb, c.showSuppressed)

// NOTE: cyclonedx is identical to embeddedVEXJSON
// The cyclonedx library only provides two BOM formats: JSON and XML
Expand Down
16 changes: 10 additions & 6 deletions grype/presenter/table/presenter.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,17 @@ type Presenter struct {
ignoredMatches []match.IgnoredMatch
packages []pkg.Package
metadataProvider vulnerability.MetadataProvider
showSuppressed bool
}

// NewPresenter is a *Presenter constructor
func NewPresenter(pb models.PresenterConfig) *Presenter {
func NewPresenter(pb models.PresenterConfig, showSuppressed bool) *Presenter {
return &Presenter{
results: pb.Matches,
ignoredMatches: pb.IgnoredMatches,
packages: pb.Packages,
metadataProvider: pb.MetadataProvider,
showSuppressed: showSuppressed,
}
}

Expand All @@ -53,13 +55,15 @@ func (pres *Presenter) Present(output io.Writer) error {
}

// Generate rows for suppressed vulnerabilities
for _, m := range pres.ignoredMatches {
row, err := createRow(m.Match, pres.metadataProvider, appendSuppressed)
if pres.showSuppressed {
for _, m := range pres.ignoredMatches {
row, err := createRow(m.Match, pres.metadataProvider, appendSuppressed)

if err != nil {
return err
if err != nil {
return err
}
rows = append(rows, row)
}
rows = append(rows, row)
}

if len(rows) == 0 {
Expand Down
66 changes: 64 additions & 2 deletions grype/presenter/table/presenter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func TestTablePresenter(t *testing.T) {
MetadataProvider: metadataProvider,
}

pres := NewPresenter(pb)
pres := NewPresenter(pb, false)

// run presenter
err := pres.Present(&buffer)
Expand Down Expand Up @@ -121,7 +121,7 @@ func TestEmptyTablePresenter(t *testing.T) {
MetadataProvider: nil,
}

pres := NewPresenter(pb)
pres := NewPresenter(pb, false)

// run presenter
err := pres.Present(&buffer)
Expand Down Expand Up @@ -171,3 +171,65 @@ func TestRemoveDuplicateRows(t *testing.T) {
}

}

func TestHidesIgnoredMatches(t *testing.T) {
var buffer bytes.Buffer
matches, ignoredMatches, packages, _, metadataProvider, _, _ := models.GenerateAnalysisWithIgnoredMatches(t, source.ImageScheme)

pb := models.PresenterConfig{
Matches: matches,
IgnoredMatches: ignoredMatches,
Packages: packages,
MetadataProvider: metadataProvider,
}

pres := NewPresenter(pb, false)

err := pres.Present(&buffer)
if err != nil {
t.Fatal(err)
}
actual := buffer.Bytes()
if *update {
testutils.UpdateGoldenFileContents(t, actual)
}

var expected = testutils.GetGoldenFileContents(t)

if !bytes.Equal(expected, actual) {
dmp := diffmatchpatch.New()
diffs := dmp.DiffMain(string(expected), string(actual), true)
t.Errorf("mismatched output:\n%s", dmp.DiffPrettyText(diffs))
}
}

func TestDisplaysIgnoredMatches(t *testing.T) {
var buffer bytes.Buffer
matches, ignoredMatches, packages, _, metadataProvider, _, _ := models.GenerateAnalysisWithIgnoredMatches(t, source.ImageScheme)

pb := models.PresenterConfig{
Matches: matches,
IgnoredMatches: ignoredMatches,
Packages: packages,
MetadataProvider: metadataProvider,
}

pres := NewPresenter(pb, true)

err := pres.Present(&buffer)
if err != nil {
t.Fatal(err)
}
actual := buffer.Bytes()
if *update {
testutils.UpdateGoldenFileContents(t, actual)
}

var expected = testutils.GetGoldenFileContents(t)

if !bytes.Equal(expected, actual) {
dmp := diffmatchpatch.New()
diffs := dmp.DiffMain(string(expected), string(actual), true)
t.Errorf("mismatched output:\n%s", dmp.DiffPrettyText(diffs))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
NAME INSTALLED FIXED-IN TYPE VULNERABILITY SEVERITY
package-1 1.1.1 rpm CVE-1999-0002 Critical
package-1 1.1.1 the-next-version rpm CVE-1999-0001 Low
package-2 2.2.2 deb CVE-1999-0001 Low (suppressed)
package-2 2.2.2 deb CVE-1999-0002 Critical (suppressed)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
NAME INSTALLED FIXED-IN TYPE VULNERABILITY SEVERITY
package-1 1.1.1 rpm CVE-1999-0002 Critical
package-1 1.1.1 the-next-version rpm CVE-1999-0001 Low

0 comments on commit c1f6772

Please sign in to comment.