Add java.Matcher configuration to includes maven upstream sha1 query (#714)

This commit is contained in:
Christopher Angelo Phillips 2022-04-13 13:01:22 -04:00 committed by GitHub
parent e77a6c8d63
commit 95f68b4c33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 425 additions and 65 deletions

View file

@ -165,6 +165,20 @@ will be resolved _relative to the specified scan directory_. Keep in mind, your
may attempt to expand wildcards, so put those parameters in single quotes, like:
`'**/*.json'`.
### External Sources
Grype can be configured to incorporate external data sources for added fidelity in vulnerability matching. This
feature is currently disabled by default. To enable this feature add the following to the grype config:
```yaml
external-sources:
enable: true
maven:
search-upstream-by-sha1: true
base-url: https://search.maven.org/solrsearch/select
```
You can also configure the base-url if you're using another registry as your maven endpoint.
### Output formats
The output format for Grype is configurable as well:
@ -504,6 +518,12 @@ add-cpes-if-none: false
# Explicitly specify a linux distribution to use as <distro>:<version> like alpine:3.10
distro:
external-sources:
enable: false
maven:
search-upstream-by-sha1: true
base-url: https://search.maven.org/solrsearch/select
db:
# check for database updates on execution
# same as GRYPE_DB_AUTO_UPDATE env var

View file

@ -18,6 +18,7 @@ import (
"github.com/anchore/grype/grype/event"
"github.com/anchore/grype/grype/grypeerr"
"github.com/anchore/grype/grype/match"
"github.com/anchore/grype/grype/matcher"
"github.com/anchore/grype/grype/pkg"
"github.com/anchore/grype/grype/presenter"
"github.com/anchore/grype/grype/vulnerability"
@ -309,7 +310,11 @@ func startWorker(userInput string, failOnSeverity *vulnerability.Severity) <-cha
applyDistroHint(&context, appConfig)
allMatches := grype.FindVulnerabilitiesForPackage(provider, context.Distro, packages...)
matchers := matcher.NewDefaultMatchers(matcher.Config{
Java: appConfig.ExternalSources.ToJavaMatcherConfig(),
})
allMatches := grype.FindVulnerabilitiesForPackage(provider, context.Distro, matchers, packages)
remainingMatches, ignoredMatches := match.ApplyIgnoreRules(allMatches, appConfig.Ignore)
if count := len(ignoredMatches); count > 0 {

4
go.mod
View file

@ -9,8 +9,8 @@ require (
github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04
github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4
github.com/anchore/packageurl-go v0.1.1-0.20220314153042-1bcd40e5206b
github.com/anchore/stereoscope v0.0.0-20220330165332-7fc73ee7b0f0
github.com/anchore/syft v0.43.0
github.com/anchore/stereoscope v0.0.0-20220406160859-c03a18a6b270
github.com/anchore/syft v0.44.0
github.com/bmatcuk/doublestar/v2 v2.0.4
github.com/docker/docker v20.10.12+incompatible
github.com/dustin/go-humanize v1.0.0

8
go.sum
View file

@ -153,10 +153,10 @@ github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4 h1:rmZG77uXgE
github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4/go.mod h1:Bkc+JYWjMCF8OyZ340IMSIi2Ebf3uwByOk6ho4wne1E=
github.com/anchore/packageurl-go v0.1.1-0.20220314153042-1bcd40e5206b h1:YJWYt/6KQXR9JR46lLHrTTYi8rcye42tKcyjREA/hvA=
github.com/anchore/packageurl-go v0.1.1-0.20220314153042-1bcd40e5206b/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4=
github.com/anchore/stereoscope v0.0.0-20220330165332-7fc73ee7b0f0 h1:mObz7bepZ6DtbIrsB2mxuOE9XEYmVtA/P/EDlKwfbjs=
github.com/anchore/stereoscope v0.0.0-20220330165332-7fc73ee7b0f0/go.mod h1:yoCLUZY0k/pYLNIy0L80p2Ko0PKVNXm8rHtgxp4OiSc=
github.com/anchore/syft v0.43.0 h1:9w52VCgSutRL08ojztoXwG6/KdOjS3w+5ePZqJNGx5o=
github.com/anchore/syft v0.43.0/go.mod h1:Po6PO927XnrHzrs8qshOjAfb/wBmu4cXEeO7FmlWFgk=
github.com/anchore/stereoscope v0.0.0-20220406160859-c03a18a6b270 h1:NmxPDR6vo3xjwCL6o+tpF1vUad/BVo+WaVSwueB9W9w=
github.com/anchore/stereoscope v0.0.0-20220406160859-c03a18a6b270/go.mod h1:yoCLUZY0k/pYLNIy0L80p2Ko0PKVNXm8rHtgxp4OiSc=
github.com/anchore/syft v0.44.0 h1:HlaWN2yLbj4Of0fATK/72BmDPMwRrQBWZ/HUmVthnj8=
github.com/anchore/syft v0.44.0/go.mod h1:m6/cWOz0aFbCL0pflHvvBgvw0qMPLVqDQa0L8+FBPVE=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=

View file

@ -29,11 +29,13 @@ func FindVulnerabilities(provider vulnerability.Provider, userImageStr string, s
return match.Matches{}, pkg.Context{}, nil, err
}
return FindVulnerabilitiesForPackage(provider, context.Distro, packages...), context, packages, nil
matchers := matcher.NewDefaultMatchers(matcher.Config{})
return FindVulnerabilitiesForPackage(provider, context.Distro, matchers, packages), context, packages, nil
}
func FindVulnerabilitiesForPackage(provider vulnerability.Provider, d *linux.Release, packages ...pkg.Package) match.Matches {
return matcher.FindMatches(provider, d, packages...)
func FindVulnerabilitiesForPackage(provider vulnerability.Provider, d *linux.Release, matchers []matcher.Matcher, packages []pkg.Package) match.Matches {
return matcher.FindMatches(provider, d, matchers, packages)
}
func LoadVulnerabilityDB(cfg db.Config, update bool) (vulnerability.Provider, vulnerability.MetadataProvider, *db.Status, error) {

View file

@ -35,6 +35,7 @@ func TestMatcherDpkg_matchBySourceIndirection(t *testing.T) {
store := newMockProvider()
actual, err := matcher.matchUpstreamPackages(store, d, p)
assert.NoError(t, err, "unexpected err from matchUpstreamPackages", err)
assert.Len(t, actual, 2, "unexpected indirect matches count")

View file

@ -1,15 +1,119 @@
package java
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"sort"
"github.com/anchore/grype/grype/distro"
"github.com/anchore/grype/grype/match"
"github.com/anchore/grype/grype/pkg"
"github.com/anchore/grype/grype/search"
"github.com/anchore/grype/grype/vulnerability"
"github.com/anchore/grype/internal/log"
syftPkg "github.com/anchore/syft/syft/pkg"
)
const (
sha1Query = `1:"%s"`
)
type Matcher struct {
SearchMavenUpstream bool
MavenSearcher
}
// MavenSearcher is the interface that wraps the GetMavenPackageBySha method.
type MavenSearcher interface {
// GetMavenPackageBySha provides an interface for building a package from maven data based on a sha1 digest
GetMavenPackageBySha(string) (*pkg.Package, error)
}
// mavenSearch implements the MavenSearcher interface
type mavenSearch struct {
client *http.Client
baseURL string
}
type mavenAPIResponse struct {
Response struct {
NumFound int `json:"numFound"`
Docs []struct {
ID string `json:"id"`
GroupID string `json:"g"`
ArtifactID string `json:"a"`
Version string `json:"v"`
P string `json:"p"`
VersionCount int `json:"versionCount"`
} `json:"docs"`
} `json:"response"`
}
func (ms *mavenSearch) GetMavenPackageBySha(sha1 string) (*pkg.Package, error) {
req, err := http.NewRequest(http.MethodGet, ms.baseURL, nil)
if err != nil {
return nil, fmt.Errorf("unable to initialize HTTP client: %w", err)
}
q := req.URL.Query()
q.Set("q", fmt.Sprintf(sha1Query, sha1))
q.Set("rows", "1")
q.Set("wt", "json")
req.URL.RawQuery = q.Encode()
resp, err := ms.client.Do(req)
if err != nil {
return nil, fmt.Errorf("sha1 search error: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("status %s from %s", resp.Status, req.URL.String())
}
var res mavenAPIResponse
if err = json.NewDecoder(resp.Body).Decode(&res); err != nil {
return nil, fmt.Errorf("json decode error: %w", err)
}
if len(res.Response.Docs) == 0 {
return nil, fmt.Errorf("digest %s: %w", sha1, errors.New("no artifact found"))
}
// artifacts might have the same SHA-1 digests.
// e.g. "javax.servlet:jstl" and "jstl:jstl"
docs := res.Response.Docs
sort.Slice(docs, func(i, j int) bool {
return docs[i].ID < docs[j].ID
})
d := docs[0]
return &pkg.Package{
Name: fmt.Sprintf("%s:%s", d.GroupID, d.ArtifactID),
Version: d.Version,
Language: syftPkg.Java,
Metadata: pkg.JavaMetadata{
PomArtifactID: d.ArtifactID,
PomGroupID: d.GroupID,
},
}, nil
}
type MatcherConfig struct {
SearchMavenUpstream bool
MavenBaseURL string
}
func NewJavaMatcher(cfg MatcherConfig) *Matcher {
return &Matcher{
cfg.SearchMavenUpstream,
&mavenSearch{
client: http.DefaultClient,
baseURL: cfg.MavenBaseURL,
},
}
}
func (m *Matcher) PackageTypes() []syftPkg.Type {
@ -21,5 +125,44 @@ func (m *Matcher) Type() match.MatcherType {
}
func (m *Matcher) Match(store vulnerability.Provider, d *distro.Distro, p pkg.Package) ([]match.Match, error) {
return search.ByCriteria(store, d, p, m.Type(), search.CommonCriteria...)
var matches []match.Match
if m.SearchMavenUpstream {
upstreamMatches, err := m.matchUpstreamMavenPackages(store, p)
if err != nil {
log.Warnf("failed to match against upstream data for %s: %v", p.Name, err)
} else {
matches = append(matches, upstreamMatches...)
}
}
criteriaMatches, err := search.ByCriteria(store, d, p, m.Type(), search.CommonCriteria...)
if err != nil {
return nil, fmt.Errorf("failed to match by exact package: %w", err)
}
matches = append(matches, criteriaMatches...)
return matches, nil
}
func (m *Matcher) matchUpstreamMavenPackages(store vulnerability.Provider, p pkg.Package) ([]match.Match, error) {
var matches []match.Match
if metadata, ok := p.Metadata.(pkg.JavaMetadata); ok {
for _, d := range metadata.ArchiveDigests {
if d.Algorithm == "sha1" {
indirectPackage, err := m.GetMavenPackageBySha(d.Value)
if err != nil {
return nil, err
}
indirectMatches, err := search.ByPackageLanguage(store, *indirectPackage, m.Type())
if err != nil {
return nil, err
}
matches = append(matches, indirectMatches...)
}
}
}
match.ConvertToIndirectMatches(matches, p)
return matches, nil
}

View file

@ -0,0 +1,69 @@
package java
import (
"github.com/anchore/grype/grype/distro"
"github.com/anchore/grype/grype/pkg"
"github.com/anchore/grype/grype/version"
"github.com/anchore/grype/grype/vulnerability"
syftPkg "github.com/anchore/syft/syft/pkg"
)
type mockProvider struct {
data map[syftPkg.Language]map[string][]vulnerability.Vulnerability
}
func (mp *mockProvider) populateData() {
mp.data[syftPkg.Java] = map[string][]vulnerability.Vulnerability{
"org.springframework.spring-webmvc": {
{
Constraint: version.MustGetConstraint(">=5.0.0,<5.1.7", version.UnknownFormat),
ID: "CVE-2014-fake-2",
},
{
Constraint: version.MustGetConstraint(">=5.0.1,<5.1.7", version.UnknownFormat),
ID: "CVE-2013-fake-3",
},
// unexpected...
{
Constraint: version.MustGetConstraint(">=5.0.0,<5.0.7", version.UnknownFormat),
ID: "CVE-2013-fake-BAD",
},
},
}
}
func newMockProvider() *mockProvider {
mp := mockProvider{
data: make(map[syftPkg.Language]map[string][]vulnerability.Vulnerability),
}
mp.populateData()
return &mp
}
type mockMavenSearcher struct {
pkg pkg.Package
}
func (m mockMavenSearcher) GetMavenPackageBySha(string) (*pkg.Package, error) {
return &m.pkg, nil
}
func newMockSearcher(pkg pkg.Package) MavenSearcher {
return mockMavenSearcher{
pkg,
}
}
func (mp *mockProvider) GetByCPE(p syftPkg.CPE) ([]vulnerability.Vulnerability, error) {
return []vulnerability.Vulnerability{}, nil
}
func (mp *mockProvider) GetByDistro(d *distro.Distro, p pkg.Package) ([]vulnerability.Vulnerability, error) {
return []vulnerability.Vulnerability{}, nil
}
func (mp *mockProvider) GetByLanguage(l syftPkg.Language, p pkg.Package) ([]vulnerability.Vulnerability, error) {
return mp.data[l][p.Name], nil
}

View file

@ -0,0 +1,62 @@
package java
import (
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/anchore/grype/grype/match"
"github.com/anchore/grype/grype/pkg"
"github.com/anchore/grype/internal"
syftPkg "github.com/anchore/syft/syft/pkg"
)
func TestMatcherJava_matchUpstreamMavenPackage(t *testing.T) {
p := pkg.Package{
ID: pkg.ID(uuid.NewString()),
Name: "org.springframework.spring-webmvc",
Version: "5.1.5.RELEASE",
Language: syftPkg.Java,
Type: syftPkg.JavaPkg,
MetadataType: pkg.JavaMetadataType,
Metadata: pkg.JavaMetadata{
ArchiveDigests: []pkg.Digest{
{
Algorithm: "sha1",
Value: "236e3bfdbdc6c86629237a74f0f11414adb4e211",
},
},
},
}
matcher := Matcher{
SearchMavenUpstream: true,
MavenSearcher: newMockSearcher(p),
}
store := newMockProvider()
actual, _ := matcher.matchUpstreamMavenPackages(store, p)
assert.Len(t, actual, 2, "unexpected matches count")
foundCVEs := internal.NewStringSet()
for _, v := range actual {
foundCVEs.Add(v.Vulnerability.ID)
require.NotEmpty(t, v.Details)
for _, d := range v.Details {
assert.Equal(t, match.ExactIndirectMatch, d.Type, "indirect match not indicated")
assert.Equal(t, matcher.Type(), d.Matcher, "failed to capture matcher type")
}
assert.Equal(t, p.Name, v.Package.Name, "failed to capture original package name")
}
for _, id := range []string{"CVE-2014-fake-2", "CVE-2013-fake-3"} {
if !foundCVEs.Contains(id) {
t.Errorf("missing discovered CVE: %s", id)
}
}
if t.Failed() {
t.Logf("discovered CVES: %+v", foundCVEs)
}
}

View file

@ -24,50 +24,30 @@ import (
syftPkg "github.com/anchore/syft/syft/pkg"
)
var controllerInstance controller
type Monitor struct {
PackagesProcessed progress.Monitorable
VulnerabilitiesDiscovered progress.Monitorable
}
func init() {
controllerInstance = newController()
// Config contains values used by individual matcher structs for advanced configuration
type Config struct {
Java java.MatcherConfig
}
type controller struct {
matchers map[syftPkg.Type][]Matcher
}
func newController() controller {
ctrlr := controller{
matchers: make(map[syftPkg.Type][]Matcher),
}
ctrlr.add(&dpkg.Matcher{})
ctrlr.add(&ruby.Matcher{})
ctrlr.add(&python.Matcher{})
ctrlr.add(&rpmdb.Matcher{})
ctrlr.add(&java.Matcher{})
ctrlr.add(&javascript.Matcher{})
ctrlr.add(&apk.Matcher{})
ctrlr.add(&msrc.Matcher{})
return ctrlr
}
func (c *controller) add(matchers ...Matcher) {
for _, m := range matchers {
for _, t := range m.PackageTypes() {
if _, ok := c.matchers[t]; ok {
c.matchers[t] = make([]Matcher, 0)
}
c.matchers[t] = append(c.matchers[t], m)
log.Debugf("adding matcher: %+v", t)
}
func NewDefaultMatchers(mc Config) []Matcher {
return []Matcher{
&dpkg.Matcher{},
&ruby.Matcher{},
&python.Matcher{},
&rpmdb.Matcher{},
java.NewJavaMatcher(mc.Java),
&javascript.Matcher{},
&apk.Matcher{},
&msrc.Matcher{},
}
}
func (c *controller) trackMatcher() (*progress.Manual, *progress.Manual) {
func trackMatcher() (*progress.Manual, *progress.Manual) {
packagesProcessed := progress.Manual{}
vulnerabilitiesDiscovered := progress.Manual{}
@ -81,9 +61,26 @@ func (c *controller) trackMatcher() (*progress.Manual, *progress.Manual) {
return &packagesProcessed, &vulnerabilitiesDiscovered
}
func (c *controller) findMatches(provider vulnerability.Provider, release *linux.Release, packages ...pkg.Package) match.Matches {
func newMatcherIndex(matchers []Matcher) map[syftPkg.Type][]Matcher {
matcherIndex := make(map[syftPkg.Type][]Matcher)
for _, m := range matchers {
for _, t := range m.PackageTypes() {
if _, ok := matcherIndex[t]; !ok {
matcherIndex[t] = make([]Matcher, 0)
}
matcherIndex[t] = append(matcherIndex[t], m)
log.Debugf("adding matcher: %+v", t)
}
}
return matcherIndex
}
func FindMatches(provider vulnerability.Provider, release *linux.Release, matchers []Matcher, packages []pkg.Package) match.Matches {
var err error
res := match.NewMatches()
matcherIndex := newMatcherIndex(matchers)
var d *distro.Distro
if release != nil {
@ -93,14 +90,14 @@ func (c *controller) findMatches(provider vulnerability.Provider, release *linux
}
}
packagesProcessed, vulnerabilitiesDiscovered := c.trackMatcher()
packagesProcessed, vulnerabilitiesDiscovered := trackMatcher()
defaultMatcher := &stock.Matcher{}
for _, p := range packages {
packagesProcessed.N++
log.Debugf("searching for vulnerability matches for pkg=%s", p)
matchers, ok := c.matchers[p.Type]
matchers, ok := matcherIndex[p.Type]
if !ok {
matchers = []Matcher{defaultMatcher}
}
@ -124,10 +121,6 @@ func (c *controller) findMatches(provider vulnerability.Provider, release *linux
return res
}
func FindMatches(provider vulnerability.Provider, d *linux.Release, packages ...pkg.Package) match.Matches {
return controllerInstance.findMatches(provider, d, packages...)
}
func logMatches(p pkg.Package, matches []match.Match) {
if len(matches) > 0 {
log.Debugf("found %d vulnerabilities for pkg=%s", len(matches), p)

View file

@ -1,8 +1,14 @@
package pkg
type JavaMetadata struct {
VirtualPath string `json:"virtualPath"`
PomArtifactID string `json:"pomArtifactID"`
PomGroupID string `json:"pomGroupID"`
ManifestName string `json:"manifestName"`
VirtualPath string `json:"virtualPath"`
PomArtifactID string `json:"pomArtifactID"`
PomGroupID string `json:"pomGroupID"`
ManifestName string `json:"manifestName"`
ArchiveDigests []Digest `json:"archiveDigests"`
}
type Digest struct {
Algorithm string `json:"algorithm"`
Value string `json:"value"`
}

View file

@ -165,11 +165,22 @@ func javaDataFromPkg(p pkg.Package) (metadata *JavaMetadata) {
}
}
var archiveDigests []Digest
if len(value.ArchiveDigests) > 0 {
for _, d := range value.ArchiveDigests {
archiveDigests = append(archiveDigests, Digest{
Algorithm: d.Algorithm,
Value: d.Value,
})
}
}
metadata = &JavaMetadata{
VirtualPath: value.VirtualPath,
PomArtifactID: artifact,
PomGroupID: group,
ManifestName: name,
VirtualPath: value.VirtualPath,
PomArtifactID: artifact,
PomGroupID: group,
ManifestName: name,
ArchiveDigests: archiveDigests,
}
} else {
log.Warnf("unable to extract Java metadata for %s", p)

View file

@ -8,6 +8,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/anchore/syft/syft/file"
syftFile "github.com/anchore/syft/syft/file"
syftPkg "github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/source"
)
@ -126,6 +127,10 @@ func TestNew(t *testing.T) {
"extra-key": "extra-value",
},
},
ArchiveDigests: []syftFile.Digest{{
Algorithm: "sha1",
Value: "236e3bfdbdc6c86629237a74f0f11414adb4e211",
}},
},
},
metadata: JavaMetadata{
@ -133,6 +138,10 @@ func TestNew(t *testing.T) {
PomArtifactID: "pom-artifact-ID-info",
PomGroupID: "pom-group-ID-info",
ManifestName: "main-section-name-info",
ArchiveDigests: []Digest{{
Algorithm: "sha1",
Value: "236e3bfdbdc6c86629237a74f0f11414adb4e211",
}},
},
},
{

View file

@ -44,6 +44,7 @@ type Application struct {
Ignore []match.IgnoreRule `yaml:"ignore" json:"ignore" mapstructure:"ignore"`
Exclusions []string `yaml:"exclude" json:"exclude" mapstructure:"exclude"`
DB database `yaml:"db" json:"db" mapstructure:"db"`
ExternalSources externalSources `yaml:"external-sources" json:"externalSources" mapstructure:"external-sources"`
Dev development `yaml:"dev" json:"dev" mapstructure:"dev"`
FailOn string `yaml:"fail-on-severity" json:"fail-on-severity" mapstructure:"fail-on-severity"`
FailOnSeverity *vulnerability.Severity `yaml:"-" json:"-"`

View file

@ -0,0 +1,39 @@
package config
import (
"github.com/spf13/viper"
"github.com/anchore/grype/grype/matcher/java"
)
const (
defaultMavenBaseURL = "https://search.maven.org/solrsearch/select"
)
type externalSources struct {
Enable bool `yaml:"enable" json:"enable" mapstructure:"enable"`
Maven maven `yaml:"maven" json:"maven" mapsructure:"maven"`
}
type maven struct {
SearchUpstreamBySha1 bool `yaml:"search-upstream" json:"searchUpstreamBySha1" mapstructure:"search-maven-upstream"`
BaseURL string `yaml:"base-url" json:"baseUrl" mapstructure:"base-url"`
}
func (cfg externalSources) loadDefaultValues(v *viper.Viper) {
v.SetDefault("external-sources.enable", false)
v.SetDefault("external-sources.maven.search-maven-upstream", true)
v.SetDefault("external-sources.maven.base-url", defaultMavenBaseURL)
}
func (cfg externalSources) ToJavaMatcherConfig() java.MatcherConfig {
// always respect if global config is disabled
smu := cfg.Maven.SearchUpstreamBySha1
if !cfg.Enable {
smu = cfg.Enable
}
return java.MatcherConfig{
SearchMavenUpstream: smu,
MavenBaseURL: cfg.Maven.BaseURL,
}
}

View file

@ -8,6 +8,7 @@ import (
"github.com/anchore/grype/grype"
"github.com/anchore/grype/grype/db"
"github.com/anchore/grype/grype/match"
"github.com/anchore/grype/grype/matcher"
"github.com/anchore/grype/grype/pkg"
"github.com/anchore/grype/grype/vulnerability"
"github.com/anchore/grype/internal"
@ -378,11 +379,9 @@ func TestMatchByImage(t *testing.T) {
t.Fatalf("could not get the source obj: %+v", err)
}
actualResults := grype.FindVulnerabilitiesForPackage(
db.NewVulnerabilityProvider(theStore),
theDistro,
pkg.FromCatalog(theCatalog, pkg.ProviderConfig{})...,
)
matchers := matcher.NewDefaultMatchers(matcher.Config{})
actualResults := grype.FindVulnerabilitiesForPackage(db.NewVulnerabilityProvider(theStore), theDistro, matchers, pkg.FromCatalog(theCatalog, pkg.ProviderConfig{}))
// build expected matches from what's discovered from the catalog
expectedMatches := test.expectedFn(*theSource, theCatalog, theStore)