Skip to content

Commit

Permalink
fix(purl): skip local Go packages (#5190)
Browse files Browse the repository at this point in the history
* fix(purl): trim a final slash

* fix(purl): skip local Go packages

* fix(purl): a few improvements
  • Loading branch information
javierfreire authored Sep 20, 2023
1 parent eea3320 commit 37af529
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 1 deletion.
7 changes: 7 additions & 0 deletions pkg/purl/purl.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ func NewPackageURL(t string, metadata types.Metadata, pkg ftypes.Package) (Packa
namespace, name = parseComposer(name)
case packageurl.TypeGolang:
namespace, name = parseGolang(name)
if name == "" {
return PackageURL{PackageURL: *packageurl.NewPackageURL("", "", "", "", nil, "")}, nil
}
case packageurl.TypeNPM:
namespace, name = parseNpm(name)
case packageurl.TypeSwift:
Expand Down Expand Up @@ -310,6 +313,10 @@ func parseMaven(pkgName string) (string, string) {

// ref. https://github.com/package-url/purl-spec/blob/a748c36ad415c8aeffe2b8a4a5d8a50d16d6d85f/PURL-TYPES.rst#golang
func parseGolang(pkgName string) (string, string) {
// The PURL will be skipped when the package name is a local path, since it can't identify a software package.
if strings.HasPrefix(pkgName, "./") || strings.HasPrefix(pkgName, "../") {
return "", ""
}
name := strings.ToLower(pkgName)
return parsePkgName(name)
}
Expand Down
16 changes: 16 additions & 0 deletions pkg/purl/purl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,22 @@ func TestNewPackageURL(t *testing.T) {
},
},
},
{
name: "golang package with a local path",
typ: ftypes.GoModule,
pkg: ftypes.Package{
Name: "./private_repos/cnrm.googlesource.com/cnrm/",
Version: "(devel)",
},
want: purl.PackageURL{
PackageURL: packageurl.PackageURL{
Type: "",
Namespace: "",
Name: "",
Version: "",
},
},
},
{
name: "hex package",
typ: ftypes.Hex,
Expand Down
6 changes: 5 additions & 1 deletion pkg/sbom/spdx/marshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,11 @@ func (m *Marshaler) pkgToSpdxPackage(t, pkgDownloadLocation string, class types.
if err != nil {
return spdx.Package{}, xerrors.Errorf("failed to parse purl (%s): %w", pkg.Name, err)
}
pkgExtRefs := []*spdx.PackageExternalReference{purlExternalReference(packageURL.String())}

var pkgExtRefs []*spdx.PackageExternalReference
if packageURL.Type != "" {
pkgExtRefs = []*spdx.PackageExternalReference{purlExternalReference(packageURL.String())}
}

var attrTexts []string
attrTexts = appendAttributionText(attrTexts, PropertyPkgID, pkg.ID)
Expand Down
112 changes: 112 additions & 0 deletions pkg/sbom/spdx/marshal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,118 @@ func TestMarshaler_Marshal(t *testing.T) {
},
},
},
{
name: "go library local",
inputReport: types.Report{
SchemaVersion: report.SchemaVersion,
ArtifactName: "go-artifact",
ArtifactType: ftypes.ArtifactFilesystem,
Results: types.Results{
{
Target: "artifact",
Class: types.ClassLangPkg,
Type: ftypes.GoBinary,
Packages: []ftypes.Package{
{
Name: "./private_repos/cnrm.googlesource.com/cnrm/",
Version: "(devel)",
},
{
Name: "golang.org/x/crypto",
Version: "v0.0.1",
},
},
},
},
},
wantSBOM: &spdx.Document{
SPDXVersion: spdx.Version,
DataLicense: spdx.DataLicense,
SPDXIdentifier: "DOCUMENT",
DocumentName: "go-artifact",
DocumentNamespace: "http://aquasecurity.github.io/trivy/filesystem/go-artifact-3ff14136-e09f-4df9-80ea-000000000001",
CreationInfo: &spdx.CreationInfo{
Creators: []common.Creator{
{
Creator: "aquasecurity",
CreatorType: "Organization",
},
{
Creator: "trivy-0.38.1",
CreatorType: "Tool",
},
},
Created: "2021-08-25T12:20:30Z",
},
Packages: []*spdx.Package{
{
PackageSPDXIdentifier: spdx.ElementID("Package-9164ae38c5cdf815"),
PackageDownloadLocation: "NONE",
PackageName: "./private_repos/cnrm.googlesource.com/cnrm/",
PackageVersion: "(devel)",
PackageLicenseConcluded: "NONE",
PackageLicenseDeclared: "NONE",
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
},
{
PackageName: "go-artifact",
PackageSPDXIdentifier: "Filesystem-e340f27468b382be",
PackageDownloadLocation: "NONE",
PackageAttributionTexts: []string{
"SchemaVersion: 2",
},
PrimaryPackagePurpose: tspdx.PackagePurposeSource,
},
{
PackageSPDXIdentifier: spdx.ElementID("Application-6666b83a5d554671"),
PackageDownloadLocation: "NONE",
PackageName: "gobinary",
PackageSourceInfo: "artifact",
PrimaryPackagePurpose: tspdx.PackagePurposeApplication,
},
{
PackageSPDXIdentifier: spdx.ElementID("Package-8451f2bc8e1f45aa"),
PackageDownloadLocation: "NONE",
PackageName: "golang.org/x/crypto",
PackageVersion: "v0.0.1",
PackageLicenseConcluded: "NONE",
PackageLicenseDeclared: "NONE",
PackageExternalReferences: []*spdx.PackageExternalReference{
{
Category: tspdx.CategoryPackageManager,
RefType: tspdx.RefTypePurl,
Locator: "pkg:golang/golang.org/x/[email protected]",
},
},
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
},
},
Relationships: []*spdx.Relationship{
{
RefA: spdx.DocElementID{ElementRefID: "DOCUMENT"},
RefB: spdx.DocElementID{ElementRefID: "Filesystem-e340f27468b382be"},
Relationship: "DESCRIBES",
},
{
RefA: spdx.DocElementID{ElementRefID: "Filesystem-e340f27468b382be"},
RefB: spdx.DocElementID{ElementRefID: "Application-6666b83a5d554671"},
Relationship: "CONTAINS",
},
{
RefA: spdx.DocElementID{ElementRefID: "Application-6666b83a5d554671"},
RefB: spdx.DocElementID{ElementRefID: "Package-9164ae38c5cdf815"},
Relationship: "CONTAINS",
},
{
RefA: spdx.DocElementID{ElementRefID: "Application-6666b83a5d554671"},
RefB: spdx.DocElementID{ElementRefID: "Package-8451f2bc8e1f45aa"},
Relationship: "CONTAINS",
},
},
},
},
}

for _, tc := range testCases {
Expand Down

0 comments on commit 37af529

Please sign in to comment.