diff --git a/syft/pkg/cataloger/golang/package.go b/syft/pkg/cataloger/golang/package.go index bc3ac8e27..f07867e4c 100644 --- a/syft/pkg/cataloger/golang/package.go +++ b/syft/pkg/cataloger/golang/package.go @@ -10,7 +10,14 @@ import ( ) func (c *goBinaryCataloger) newGoBinaryPackage(dep *debug.Module, m pkg.GolangBinaryBuildinfoEntry, licenses []pkg.License, locations ...file.Location) pkg.Package { + // Similar to syft/pkg/cataloger/golang/parse_go_mod.go logic - use original path for relative replacements + finalPath := dep.Path if dep.Replace != nil { + if strings.HasPrefix(dep.Replace.Path, ".") || strings.HasPrefix(dep.Replace.Path, "/") { + finalPath = dep.Path + } else { + finalPath = dep.Replace.Path + } dep = dep.Replace } @@ -23,10 +30,10 @@ func (c *goBinaryCataloger) newGoBinaryPackage(dep *debug.Module, m pkg.GolangBi } p := pkg.Package{ - Name: dep.Path, + Name: finalPath, Version: version, Licenses: pkg.NewLicenseSet(licenses...), - PURL: packageURL(dep.Path, version), + PURL: packageURL(finalPath, version), Language: pkg.Go, Type: pkg.GoModulePkg, Locations: file.NewLocationSet(locations...), diff --git a/syft/pkg/cataloger/golang/package_test.go b/syft/pkg/cataloger/golang/package_test.go index 548e6eeeb..199a5d07e 100644 --- a/syft/pkg/cataloger/golang/package_test.go +++ b/syft/pkg/cataloger/golang/package_test.go @@ -1,6 +1,7 @@ package golang import ( + "runtime/debug" "testing" "github.com/stretchr/testify/assert" @@ -54,3 +55,67 @@ func Test_packageURL(t *testing.T) { }) } } + +func Test_newGoBinaryPackage_relativeReplace(t *testing.T) { + tests := []struct { + name string + dep *debug.Module + expectedName string + }{ + { + name: "relative replace with ../", + dep: &debug.Module{ + Path: "github.com/aws/aws-sdk-go-v2", + Version: "(devel)", + Replace: &debug.Module{ + Path: "../../", + Version: "(devel)", + }, + }, + expectedName: "github.com/aws/aws-sdk-go-v2", // should use original path, not relative + }, + { + name: "relative replace with ./", + dep: &debug.Module{ + Path: "github.com/example/module", + Version: "v1.0.0", + Replace: &debug.Module{ + Path: "./local", + Version: "v0.0.0", + }, + }, + expectedName: "github.com/example/module", // should use original path + }, + { + name: "absolute replace", + dep: &debug.Module{ + Path: "github.com/old/module", + Version: "v1.0.0", + Replace: &debug.Module{ + Path: "github.com/new/module", + Version: "v2.0.0", + }, + }, + expectedName: "github.com/new/module", // should use replacement path + }, + { + name: "no replace", + dep: &debug.Module{ + Path: "github.com/normal/module", + Version: "v1.0.0", + }, + expectedName: "github.com/normal/module", // should use original path + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + cataloger := &goBinaryCataloger{} + result := cataloger.newGoBinaryPackage(test.dep, pkg.GolangBinaryBuildinfoEntry{}, nil) + + assert.Equal(t, test.expectedName, result.Name) + assert.Equal(t, pkg.Go, result.Language) + assert.Equal(t, pkg.GoModulePkg, result.Type) + }) + } +}