From 7e616c04cd3378f78ff215fa98a3a20a2067ce87 Mon Sep 17 00:00:00 2001 From: Dan Luhring Date: Wed, 10 Apr 2024 18:03:04 -0400 Subject: [PATCH] fix: use Go main module version 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 --- grype/matcher/golang/matcher.go | 13 ++++++++----- grype/matcher/golang/matcher_test.go | 8 ++++---- grype/version/golang_version_test.go | 12 ++++++++++++ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/grype/matcher/golang/matcher.go b/grype/matcher/golang/matcher.go index ef1c6b049bb..3105e4efd4e 100644 --- a/grype/matcher/golang/matcher.go +++ b/grype/matcher/golang/matcher.go @@ -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 } diff --git a/grype/matcher/golang/matcher_test.go b/grype/matcher/golang/matcher_test.go index 9f17db89535..c9b3d417e3a 100644 --- a/grype/matcher/golang/matcher_test.go +++ b/grype/matcher/golang/matcher_test.go @@ -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), diff --git a/grype/version/golang_version_test.go b/grype/version/golang_version_test.go index 875333f1f92..283c1312b1c 100644 --- a/grype/version/golang_version_test.go +++ b/grype/version/golang_version_test.go @@ -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",