fix(go): use ldflags version for all pseudo-versions (#10037)

This commit is contained in:
DmitriyLewen
2026-01-13 16:45:18 +06:00
committed by GitHub
parent f0e23ead66
commit 3c0ab97e10
3 changed files with 75 additions and 4 deletions

View File

@@ -0,0 +1,8 @@
package binary
// Bridge to expose binary parser internals to tests in the binary_test package.
// ChooseMainVersion exports chooseMainVersion for testing.
func (p *Parser) ChooseMainVersion(version, ldflagsVersion string) string {
return p.chooseMainVersion(version, ldflagsVersion)
}

View File

@@ -10,6 +10,7 @@ import (
"github.com/mattn/go-shellwords"
"github.com/spf13/pflag"
"golang.org/x/mod/module"
"golang.org/x/mod/semver"
"golang.org/x/xerrors"
@@ -109,10 +110,7 @@ func (p *Parser) Parse(_ context.Context, r xio.ReadSeekerAt) ([]ftypes.Package,
// See https://github.com/aquasecurity/trivy/issues/1837#issuecomment-1832523477.
version := p.checkVersion(info.Main.Path, info.Main.Version)
ldflagsVersion := p.ParseLDFlags(info.Main.Path, ldflags)
if version == "" || (strings.HasPrefix(version, "v0.0.0") && ldflagsVersion != "") {
version = ldflagsVersion
}
version = p.chooseMainVersion(version, ldflagsVersion)
root := ftypes.Package{
ID: dependency.ID(ftypes.GoBinary, info.Main.Path, version),
@@ -149,6 +147,18 @@ func (p *Parser) checkVersion(name, version string) string {
return version
}
// chooseMainVersion determines which version to use for the main module.
// It prefers the ldflags version when:
// - The build info version is empty, OR
// - The build info version is a pseudo-version AND ldflags version is available
// This handles cases where actual release versions are injected via -ldflags.
func (p *Parser) chooseMainVersion(version, ldflagsVersion string) string {
if version == "" || (module.IsPseudoVersion(version) && ldflagsVersion != "") {
return ldflagsVersion
}
return version
}
func (p *Parser) ldFlags(settings []debug.BuildSetting) []string {
for _, setting := range settings {
if setting.Key != "-ldflags" {

View File

@@ -235,6 +235,59 @@ func TestParse(t *testing.T) {
}
}
func TestParser_ChooseMainVersion(t *testing.T) {
tests := []struct {
name string
version string
ldflagsVersion string
want string
}{
{
name: "v0.0.0 pseudo-version with ldflags",
version: "v0.0.0-20210121094942-22b2f8951d46",
ldflagsVersion: "v1.2.3",
want: "v1.2.3",
},
{
name: "v2.x pseudo-version with ldflags",
version: "v2.0.0-20251210145848-560ea94fc7d6",
ldflagsVersion: "v2.83.2",
want: "v2.83.2",
},
{
name: "v1.x pseudo-version with ldflags",
version: "v1.0.1-0.20220426205730-d0a4cdb22955",
ldflagsVersion: "v1.5.0",
want: "v1.5.0",
},
{
name: "regular semver version with ldflags",
version: "v1.2.3",
ldflagsVersion: "v1.2.4",
want: "v1.2.3",
},
{
name: "empty version with ldflags",
version: "",
ldflagsVersion: "v1.2.3",
want: "v1.2.3",
},
{
name: "pseudo-version without ldflags",
version: "v2.0.0-20251210145848-560ea94fc7d6",
ldflagsVersion: "",
want: "v2.0.0-20251210145848-560ea94fc7d6",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := binary.NewParser()
got := p.ChooseMainVersion(tt.version, tt.ldflagsVersion)
assert.Equal(t, tt.want, got)
})
}
}
func TestParser_ParseLDFlags(t *testing.T) {
type args struct {
name string