mirror of
https://github.com/anchore/grype
synced 2024-11-10 06:34:13 +00:00
config: add config opt in golang pseudo version main module comparison (#1816)
config: add config opt in golang pseudo version main module comparison --------- Signed-off-by: Christopher Phillips <christopher.phillips@anchore.com>
This commit is contained in:
parent
28df30c0ed
commit
b7ffbeee53
5 changed files with 84 additions and 37 deletions
|
@ -838,6 +838,7 @@ match:
|
|||
using-cpes: false
|
||||
# even if CPE matching is disabled, make an exception when scanning for "stdlib".
|
||||
always-use-cpe-for-stdlib: true
|
||||
allow-main-module-pseudo-version-comparison: true
|
||||
stock:
|
||||
using-cpes: true
|
||||
```
|
||||
|
|
|
@ -291,8 +291,9 @@ func getMatchers(opts *options.Grype) []matcher.Matcher {
|
|||
Dotnet: dotnet.MatcherConfig(opts.Match.Dotnet),
|
||||
Javascript: javascript.MatcherConfig(opts.Match.Javascript),
|
||||
Golang: golang.MatcherConfig{
|
||||
UseCPEs: opts.Match.Golang.UseCPEs,
|
||||
AlwaysUseCPEForStdlib: opts.Match.Golang.AlwaysUseCPEForStdlib,
|
||||
UseCPEs: opts.Match.Golang.UseCPEs,
|
||||
AlwaysUseCPEForStdlib: opts.Match.Golang.AlwaysUseCPEForStdlib,
|
||||
AllowMainModulePseudoVersionComparison: opts.Match.Golang.AllowMainModulePseudoVersionComparison,
|
||||
},
|
||||
Stock: stock.MatcherConfig(opts.Match.Stock),
|
||||
},
|
||||
|
|
|
@ -17,8 +17,9 @@ type matcherConfig struct {
|
|||
}
|
||||
|
||||
type golangConfig struct {
|
||||
matcherConfig `yaml:",inline" mapstructure:",squash"`
|
||||
AlwaysUseCPEForStdlib bool `yaml:"always-use-cpe-for-stdlib" json:"always-use-cpe-for-stdlib" mapstructure:"always-use-cpe-for-stdlib"` // if CPEs should be used during matching
|
||||
matcherConfig `yaml:",inline" mapstructure:",squash"`
|
||||
AlwaysUseCPEForStdlib bool `yaml:"always-use-cpe-for-stdlib" json:"always-use-cpe-for-stdlib" mapstructure:"always-use-cpe-for-stdlib"` // if CPEs should be used during matching
|
||||
AllowMainModulePseudoVersionComparison bool `yaml:"allow-main-module-pseudo-version-comparison" json:"allow-main-module-pseudo-version-comparison" mapstructure:"allow-main-module-pseudo-version-comparison"` // if pseudo versions should be compared
|
||||
}
|
||||
|
||||
func defaultGolangConfig() golangConfig {
|
||||
|
@ -26,7 +27,8 @@ func defaultGolangConfig() golangConfig {
|
|||
matcherConfig: matcherConfig{
|
||||
UseCPEs: false,
|
||||
},
|
||||
AlwaysUseCPEForStdlib: true,
|
||||
AlwaysUseCPEForStdlib: true,
|
||||
AllowMainModulePseudoVersionComparison: true,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,9 @@ type Matcher struct {
|
|||
}
|
||||
|
||||
type MatcherConfig struct {
|
||||
UseCPEs bool
|
||||
AlwaysUseCPEForStdlib bool
|
||||
UseCPEs bool
|
||||
AlwaysUseCPEForStdlib bool
|
||||
AllowMainModulePseudoVersionComparison bool
|
||||
}
|
||||
|
||||
func NewGolangMatcher(cfg MatcherConfig) *Matcher {
|
||||
|
@ -49,7 +50,13 @@ func (m *Matcher) Match(store vulnerability.Provider, d *distro.Distro, p pkg.Pa
|
|||
// Syft has some fallback mechanisms to come up with a more sane version value
|
||||
// depending on the scenario. But if none of these apply, the Go-set value of
|
||||
// "(devel)" is used, which is altogether unhelpful for vulnerability matching.
|
||||
isNotCorrected := strings.HasPrefix(p.Version, "(devel)")
|
||||
var isNotCorrected bool
|
||||
if m.cfg.AllowMainModulePseudoVersionComparison {
|
||||
isNotCorrected = strings.HasPrefix(p.Version, "(devel)")
|
||||
} else {
|
||||
// when AllowPseudoVersionComparison is false
|
||||
isNotCorrected = strings.HasPrefix(p.Version, "v0.0.0-") || strings.HasPrefix(p.Version, "(devel)")
|
||||
}
|
||||
if p.Name == mainModule && isNotCorrected {
|
||||
return matches, nil
|
||||
}
|
||||
|
|
|
@ -15,38 +15,74 @@ import (
|
|||
syftPkg "github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
func TestMatcher_DropMainPackageIfNoVersion(t *testing.T) {
|
||||
|
||||
mainModuleMetadata := pkg.GolangBinMetadata{
|
||||
MainModule: "istio.io/istio",
|
||||
func TestMatcher_DropMainPackageGivenVersionInfo(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
subjectWithoutMainModule pkg.Package
|
||||
mainModuleData pkg.GolangBinMetadata
|
||||
allowPsuedoVersionComparison bool
|
||||
expectedMatchCount int
|
||||
}{
|
||||
{
|
||||
name: "main module with version is matched when pseudo version comparison is allowed",
|
||||
subjectWithoutMainModule: pkg.Package{
|
||||
ID: pkg.ID(uuid.NewString()),
|
||||
Name: "istio.io/istio",
|
||||
Version: "v0.0.0-20220606222826-f59ce19ec6b6",
|
||||
Type: syftPkg.GoModulePkg,
|
||||
Language: syftPkg.Go,
|
||||
Metadata: pkg.GolangBinMetadata{},
|
||||
},
|
||||
mainModuleData: pkg.GolangBinMetadata{
|
||||
MainModule: "istio.io/istio",
|
||||
},
|
||||
allowPsuedoVersionComparison: true,
|
||||
expectedMatchCount: 1,
|
||||
},
|
||||
{
|
||||
name: "main module with version is NOT matched when pseudo version comparison is disabled",
|
||||
subjectWithoutMainModule: pkg.Package{
|
||||
ID: pkg.ID(uuid.NewString()),
|
||||
Name: "istio.io/istio",
|
||||
Version: "v0.0.0-20220606222826-f59ce19ec6b6",
|
||||
Type: syftPkg.GoModulePkg,
|
||||
Language: syftPkg.Go,
|
||||
Metadata: pkg.GolangBinMetadata{},
|
||||
},
|
||||
mainModuleData: pkg.GolangBinMetadata{
|
||||
MainModule: "istio.io/istio",
|
||||
},
|
||||
allowPsuedoVersionComparison: false,
|
||||
expectedMatchCount: 0,
|
||||
},
|
||||
}
|
||||
|
||||
subjectWithoutMainModule := pkg.Package{
|
||||
ID: pkg.ID(uuid.NewString()),
|
||||
Name: "istio.io/istio",
|
||||
Version: "v0.0.0-20220606222826-f59ce19ec6b6",
|
||||
Type: syftPkg.GoModulePkg,
|
||||
Language: syftPkg.Go,
|
||||
Metadata: pkg.GolangBinMetadata{},
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
mainModuleMetadata := test.mainModuleData
|
||||
subjectWithoutMainModule := test.subjectWithoutMainModule
|
||||
|
||||
subjectWithMainModule := subjectWithoutMainModule
|
||||
subjectWithMainModule.Metadata = mainModuleMetadata
|
||||
|
||||
subjectWithMainModuleAsDevel := subjectWithMainModule
|
||||
subjectWithMainModuleAsDevel.Version = "(devel)"
|
||||
|
||||
matcher := NewGolangMatcher(MatcherConfig{
|
||||
AllowMainModulePseudoVersionComparison: test.allowPsuedoVersionComparison,
|
||||
})
|
||||
store := newMockProvider()
|
||||
|
||||
preTest, _ := matcher.Match(store, nil, subjectWithoutMainModule)
|
||||
assert.Len(t, preTest, 1, "should have matched the package when there is not a main module")
|
||||
|
||||
actual, _ := matcher.Match(store, nil, subjectWithMainModule)
|
||||
assert.Len(t, actual, test.expectedMatchCount, "should match the main module depending on config (i.e. 1 match)")
|
||||
|
||||
actual, _ = matcher.Match(store, nil, subjectWithMainModuleAsDevel)
|
||||
assert.Len(t, actual, 0, "unexpected match count; should never match main module (devel)")
|
||||
})
|
||||
}
|
||||
|
||||
subjectWithMainModule := subjectWithoutMainModule
|
||||
subjectWithMainModule.Metadata = mainModuleMetadata
|
||||
|
||||
subjectWithMainModuleAsDevel := subjectWithMainModule
|
||||
subjectWithMainModuleAsDevel.Version = "(devel)"
|
||||
|
||||
matcher := NewGolangMatcher(MatcherConfig{})
|
||||
store := newMockProvider()
|
||||
|
||||
preTest, _ := matcher.Match(store, nil, subjectWithoutMainModule)
|
||||
assert.Len(t, preTest, 1, "should have matched the package when there is not a main module")
|
||||
|
||||
actual, _ := matcher.Match(store, nil, subjectWithMainModule)
|
||||
assert.Len(t, actual, 1, "should match the main module (i.e. 1 match)")
|
||||
|
||||
actual, _ = matcher.Match(store, nil, subjectWithMainModuleAsDevel)
|
||||
assert.Len(t, actual, 0, "unexpected match count; should not match main module (devel)")
|
||||
}
|
||||
|
||||
func TestMatcher_SearchForStdlib(t *testing.T) {
|
||||
|
|
Loading…
Reference in a new issue