From 3c0ab97e10dc451a7fb91ef6283a932c9c4db6bf Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Tue, 13 Jan 2026 16:45:18 +0600 Subject: [PATCH] fix(go): use ldflags version for all pseudo-versions (#10037) --- .../parser/golang/binary/export_test.go | 8 +++ pkg/dependency/parser/golang/binary/parse.go | 18 +++++-- .../parser/golang/binary/parse_test.go | 53 +++++++++++++++++++ 3 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 pkg/dependency/parser/golang/binary/export_test.go diff --git a/pkg/dependency/parser/golang/binary/export_test.go b/pkg/dependency/parser/golang/binary/export_test.go new file mode 100644 index 0000000000..db6e75e613 --- /dev/null +++ b/pkg/dependency/parser/golang/binary/export_test.go @@ -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) +} diff --git a/pkg/dependency/parser/golang/binary/parse.go b/pkg/dependency/parser/golang/binary/parse.go index 4e5df8ec34..0a37dc28d8 100644 --- a/pkg/dependency/parser/golang/binary/parse.go +++ b/pkg/dependency/parser/golang/binary/parse.go @@ -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" { diff --git a/pkg/dependency/parser/golang/binary/parse_test.go b/pkg/dependency/parser/golang/binary/parse_test.go index 67d4ebe984..4d8e243500 100644 --- a/pkg/dependency/parser/golang/binary/parse_test.go +++ b/pkg/dependency/parser/golang/binary/parse_test.go @@ -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