fix: use Go main module version (#1797)

When its helpful, that is. This doesnt change the behavior of matching a main module with "(devel") as the version, but in cases where a more useful version is provided, such as when Syft was able to compute a reasonable pseudoversion, we use the version in for best effort matching.

Signed-off-by: Dan Luhring <dluhring@chainguard.dev>
This commit is contained in:
Dan Luhring 2024-04-16 11:06:17 -04:00 committed by GitHub
parent a7cbe3a26c
commit 6dde5ce9f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 24 additions and 9 deletions

View file

@ -42,11 +42,14 @@ func (m *Matcher) Match(store vulnerability.Provider, d *distro.Distro, p pkg.Pa
mainModule = m.MainModule
}
// Golang currently does not have a standard way of incorporating the vcs version
// into the compiled binary: https://github.com/golang/go/issues/50603
// current version information for the main module is incomplete leading to multiple FP
// TODO: remove this exclusion when vcs information is included in future go version
isNotCorrected := strings.HasPrefix(p.Version, "v0.0.0-") || strings.HasPrefix(p.Version, "(devel)")
// Golang currently does not have a standard way of incorporating the main
// module's version into the compiled binary:
// https://github.com/golang/go/issues/50603.
//
// 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)")
if p.Name == mainModule && isNotCorrected {
return matches, nil
}

View file

@ -15,7 +15,7 @@ import (
syftPkg "github.com/anchore/syft/syft/pkg"
)
func TestMatcher_DropMainPackage(t *testing.T) {
func TestMatcher_DropMainPackageIfNoVersion(t *testing.T) {
mainModuleMetadata := pkg.GolangBinMetadata{
MainModule: "istio.io/istio",
@ -43,7 +43,7 @@ func TestMatcher_DropMainPackage(t *testing.T) {
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, 0, "unexpected match count; should not match main module")
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)")
@ -174,13 +174,13 @@ type mockProvider struct {
}
func (mp *mockProvider) Get(id, namespace string) ([]vulnerability.Vulnerability, error) {
//TODO implement me
// TODO implement me
panic("implement me")
}
func (mp *mockProvider) populateData() {
mp.data[syftPkg.Go] = map[string][]vulnerability.Vulnerability{
// for TestMatcher_DropMainPackage
// for TestMatcher_DropMainPackageIfNoVersion
"istio.io/istio": {
{
Constraint: version.MustGetConstraint("< 5.0.7", version.UnknownFormat),

View file

@ -131,6 +131,18 @@ func TestCompareGolangVersions(t *testing.T) {
otherVersion: "v0.0.0-20180116102854-5a71ef0e047d",
want: 1,
},
{
name: "pseudoversion less than other pseudoversion",
thisVersion: "v0.0.0-20170116102854-1ef0e047d5a7",
otherVersion: "v0.0.0-20180116102854-5a71ef0e047d",
want: -1,
},
{
name: "pseudoversion greater than other pseudoversion",
thisVersion: "v0.0.0-20190116102854-8a3f0e047d5a",
otherVersion: "v0.0.0-20180116102854-5a71ef0e047d",
want: 1,
},
{
name: "+incompatible doesn't break equality",
thisVersion: "v3.2.0",