Adjust arch qualifier for source PURLs

Signed-off-by: swadaptive <268603322+swadaptive@users.noreply.github.com>
This commit is contained in:
swadaptive
2026-09-30 12:56:05 -04:00
committed by Alex Goodman
parent 13c6591cb2
commit d53a8d283f
4 changed files with 34 additions and 30 deletions
@@ -74,7 +74,7 @@
"purl": "pkg:rpm/centos/bind-export-libs@9.11.13-3.el8?arch=x86_64&distro=centos-8&epoch=32&upstream=bind-9.11.13-3.el8.src.rpm", "purl": "pkg:rpm/centos/bind-export-libs@9.11.13-3.el8?arch=x86_64&distro=centos-8&epoch=32&upstream=bind-9.11.13-3.el8.src.rpm",
"externalReferences": [ "externalReferences": [
{ {
"url": "pkg:rpm/centos/bind@9.11.13-3.el8?arch=source&distro=centos-8&epoch=32", "url": "pkg:rpm/centos/bind@9.11.13-3.el8?arch=src&distro=centos-8&epoch=32",
"type": "source-distribution" "type": "source-distribution"
} }
], ],
@@ -158,7 +158,7 @@
"purl": "pkg:alpm/arch/gcc-libs@13.2.1-3?arch=x86_64&distro=arch-rolling&upstream=gcc", "purl": "pkg:alpm/arch/gcc-libs@13.2.1-3?arch=x86_64&distro=arch-rolling&upstream=gcc",
"externalReferences": [ "externalReferences": [
{ {
"url": "pkg:alpm/arch/gcc@13.2.1-3?arch=source&distro=arch-rolling", "url": "pkg:alpm/arch/gcc@13.2.1-3?distro=arch-rolling",
"type": "source-distribution" "type": "source-distribution"
} }
], ],
@@ -209,7 +209,7 @@
"purl": "pkg:apk/alpine/libc-utils@0.7.2-r3?arch=x86_64&distro=alpine-3.16.3&upstream=libc-dev", "purl": "pkg:apk/alpine/libc-utils@0.7.2-r3?arch=x86_64&distro=alpine-3.16.3&upstream=libc-dev",
"externalReferences": [ "externalReferences": [
{ {
"url": "pkg:apk/alpine/libc-dev@0.7.2-r3?arch=source&distro=alpine-3.16.3", "url": "pkg:apk/alpine/libc-dev@0.7.2-r3?distro=alpine-3.16.3",
"type": "source-distribution" "type": "source-distribution"
} }
], ],
@@ -41,7 +41,7 @@
<purl>pkg:rpm/centos/bind-export-libs@9.11.13-3.el8?arch=x86_64&amp;distro=centos-8&amp;epoch=32&amp;upstream=bind-9.11.13-3.el8.src.rpm</purl> <purl>pkg:rpm/centos/bind-export-libs@9.11.13-3.el8?arch=x86_64&amp;distro=centos-8&amp;epoch=32&amp;upstream=bind-9.11.13-3.el8.src.rpm</purl>
<externalReferences> <externalReferences>
<reference type="source-distribution"> <reference type="source-distribution">
<url>pkg:rpm/centos/bind@9.11.13-3.el8?arch=source&amp;distro=centos-8&amp;epoch=32</url> <url>pkg:rpm/centos/bind@9.11.13-3.el8?arch=src&amp;distro=centos-8&amp;epoch=32</url>
</reference> </reference>
</externalReferences> </externalReferences>
<properties> <properties>
@@ -75,7 +75,7 @@
<purl>pkg:alpm/arch/gcc-libs@13.2.1-3?arch=x86_64&amp;distro=arch-rolling&amp;upstream=gcc</purl> <purl>pkg:alpm/arch/gcc-libs@13.2.1-3?arch=x86_64&amp;distro=arch-rolling&amp;upstream=gcc</purl>
<externalReferences> <externalReferences>
<reference type="source-distribution"> <reference type="source-distribution">
<url>pkg:alpm/arch/gcc@13.2.1-3?arch=source&amp;distro=arch-rolling</url> <url>pkg:alpm/arch/gcc@13.2.1-3?distro=arch-rolling</url>
</reference> </reference>
</externalReferences> </externalReferences>
<properties> <properties>
@@ -96,7 +96,7 @@
<purl>pkg:apk/alpine/libc-utils@0.7.2-r3?arch=x86_64&amp;distro=alpine-3.16.3&amp;upstream=libc-dev</purl> <purl>pkg:apk/alpine/libc-utils@0.7.2-r3?arch=x86_64&amp;distro=alpine-3.16.3&amp;upstream=libc-dev</purl>
<externalReferences> <externalReferences>
<reference type="source-distribution"> <reference type="source-distribution">
<url>pkg:apk/alpine/libc-dev@0.7.2-r3?arch=source&amp;distro=alpine-3.16.3</url> <url>pkg:apk/alpine/libc-dev@0.7.2-r3?distro=alpine-3.16.3</url>
</reference> </reference>
</externalReferences> </externalReferences>
<properties> <properties>
@@ -88,7 +88,7 @@ func encodeExternalReferences(p pkg.Package) *[]cyclonedx.ExternalReference {
} }
func encodeSourcePackageExternalReference(p pkg.Package) *cyclonedx.ExternalReference { func encodeSourcePackageExternalReference(p pkg.Package) *cyclonedx.ExternalReference {
name, version := sourceCoordinates(p) name, version, arch := sourceCoordinates(p)
if name == "" || version == "" { if name == "" || version == "" {
return nil return nil
} }
@@ -103,7 +103,11 @@ func encodeSourcePackageExternalReference(p pkg.Package) *cyclonedx.ExternalRefe
qualifiers := pkgPurl.Qualifiers.Map() qualifiers := pkgPurl.Qualifiers.Map()
delete(qualifiers, pkg.PURLQualifierUpstream) delete(qualifiers, pkg.PURLQualifierUpstream)
qualifiers[pkg.PURLQualifierArch] = "source" delete(qualifiers, pkg.PURLQualifierArch)
if arch != "" {
qualifiers[pkg.PURLQualifierArch] = arch
}
srcPurl := packageurl.NewPackageURL( srcPurl := packageurl.NewPackageURL(
pkgPurl.Type, pkgPurl.Type,
@@ -120,11 +124,11 @@ func encodeSourcePackageExternalReference(p pkg.Package) *cyclonedx.ExternalRefe
} }
} }
func sourceCoordinates(p pkg.Package) (name, version string) { func sourceCoordinates(p pkg.Package) (name, version, arch string) {
switch metadata := p.Metadata.(type) { switch metadata := p.Metadata.(type) {
case pkg.ApkDBEntry: case pkg.ApkDBEntry:
if metadata.OriginPackage != "" && metadata.OriginPackage != metadata.Package { if metadata.OriginPackage != "" && metadata.OriginPackage != metadata.Package {
return metadata.OriginPackage, metadata.Version return metadata.OriginPackage, metadata.Version, ""
} }
case pkg.DpkgDBEntry: case pkg.DpkgDBEntry:
return dpkgSourceCoordinates(metadata) return dpkgSourceCoordinates(metadata)
@@ -136,35 +140,35 @@ func sourceCoordinates(p pkg.Package) (name, version string) {
return rpmSourceCoordinates(metadata.SourceRpm) return rpmSourceCoordinates(metadata.SourceRpm)
case pkg.AlpmDBEntry: case pkg.AlpmDBEntry:
if metadata.BasePackage != "" { if metadata.BasePackage != "" {
return metadata.BasePackage, metadata.Version return metadata.BasePackage, metadata.Version, ""
} }
} }
return "", "" return "", "", ""
} }
func dpkgSourceCoordinates(entry pkg.DpkgDBEntry) (name, version string) { func dpkgSourceCoordinates(entry pkg.DpkgDBEntry) (name, version, arch string) {
if entry.Source == "" { if entry.Source == "" {
return "", "" return "", "", ""
} }
if entry.SourceVersion != "" { if entry.SourceVersion != "" {
return entry.Source, entry.SourceVersion return entry.Source, entry.SourceVersion, "source"
} }
return entry.Source, entry.Version return entry.Source, entry.Version, "source"
} }
func rpmSourceCoordinates(sourceRpm string) (name, version string) { func rpmSourceCoordinates(sourceRpm string) (name, version, arch string) {
// <name>-<version>-<release>.src.rpm // <name>-<version>-<release>.src.rpm
sourceRpm = strings.TrimSuffix(sourceRpm, ".rpm") sourceRpm = strings.TrimSuffix(sourceRpm, ".rpm")
sourceRpm = strings.TrimSuffix(strings.TrimSuffix(sourceRpm, ".src"), ".nosrc") sourceRpm = strings.TrimSuffix(strings.TrimSuffix(sourceRpm, ".src"), ".nosrc")
release := strings.LastIndex(sourceRpm, "-") release := strings.LastIndex(sourceRpm, "-")
if release < 0 { if release < 0 {
return "", "" return "", "", ""
} }
ver := strings.LastIndex(sourceRpm[:release], "-") ver := strings.LastIndex(sourceRpm[:release], "-")
if ver < 0 { if ver < 0 {
return "", "" return "", "", ""
} }
return sourceRpm[:ver], sourceRpm[ver+1:] return sourceRpm[:ver], sourceRpm[ver+1:], "src"
} }
// supported algorithm in cycloneDX as of 1.4 // supported algorithm in cycloneDX as of 1.4
@@ -145,7 +145,7 @@ func Test_encodeExternalReferences(t *testing.T) {
} }
func Test_encodeSourcePackage(t *testing.T) { func Test_encodeSourcePackage(t *testing.T) {
rpm_epoch := 32 rpmEpoch := 32
tests := []struct { tests := []struct {
name string name string
input pkg.Package input pkg.Package
@@ -186,7 +186,7 @@ func Test_encodeSourcePackage(t *testing.T) {
}, },
}, },
expected: &cyclonedx.ExternalReference{ expected: &cyclonedx.ExternalReference{
Type: cyclonedx.ERTypeSourceDistribution, URL: "pkg:apk/alpine/libc-dev@0.7.2-r3?arch=source&distro=alpine-3.16.3", Type: cyclonedx.ERTypeSourceDistribution, URL: "pkg:apk/alpine/libc-dev@0.7.2-r3?distro=alpine-3.16.3",
}, },
}, },
{ {
@@ -287,13 +287,13 @@ func Test_encodeSourcePackage(t *testing.T) {
Name: "bind-export-libs", Name: "bind-export-libs",
Version: "9.11.13", Version: "9.11.13",
Release: "3.el8", Release: "3.el8",
Epoch: &rpm_epoch, Epoch: &rpmEpoch,
Arch: "x86_64", Arch: "x86_64",
SourceRpm: "bind-9.11.13-3.el8.src.rpm", SourceRpm: "bind-9.11.13-3.el8.src.rpm",
}, },
}, },
expected: &cyclonedx.ExternalReference{ expected: &cyclonedx.ExternalReference{
Type: cyclonedx.ERTypeSourceDistribution, URL: "pkg:rpm/centos/bind@9.11.13-3.el8?arch=source&distro=centos-8&epoch=32", Type: cyclonedx.ERTypeSourceDistribution, URL: "pkg:rpm/centos/bind@9.11.13-3.el8?arch=src&distro=centos-8&epoch=32",
}, },
}, },
{ {
@@ -307,13 +307,13 @@ func Test_encodeSourcePackage(t *testing.T) {
Name: "some-package", Name: "some-package",
Version: "1.0.0", Version: "1.0.0",
Release: "1.el8", Release: "1.el8",
Epoch: &rpm_epoch, Epoch: &rpmEpoch,
Arch: "x86_64", Arch: "x86_64",
SourceRpm: "some-package-1.0.0-1.el8.src.rpm", SourceRpm: "some-package-1.0.0-1.el8.src.rpm",
}, },
}, },
expected: &cyclonedx.ExternalReference{ expected: &cyclonedx.ExternalReference{
Type: cyclonedx.ERTypeSourceDistribution, URL: "pkg:rpm/centos/some-package@1.0.0-1.el8?arch=source&distro=centos-8&epoch=32", Type: cyclonedx.ERTypeSourceDistribution, URL: "pkg:rpm/centos/some-package@1.0.0-1.el8?arch=src&distro=centos-8&epoch=32",
}, },
}, },
{ {
@@ -327,13 +327,13 @@ func Test_encodeSourcePackage(t *testing.T) {
Name: "bind-export-libs", Name: "bind-export-libs",
Version: "9.11.13", Version: "9.11.13",
Release: "3.el8", Release: "3.el8",
Epoch: &rpm_epoch, Epoch: &rpmEpoch,
Arch: "x86_64", Arch: "x86_64",
SourceRpm: "bind-9.11.13-3.el8.src.rpm", SourceRpm: "bind-9.11.13-3.el8.src.rpm",
}, },
}, },
expected: &cyclonedx.ExternalReference{ expected: &cyclonedx.ExternalReference{
Type: cyclonedx.ERTypeSourceDistribution, URL: "pkg:rpm/bind@9.11.13-3.el8?arch=source&epoch=32", Type: cyclonedx.ERTypeSourceDistribution, URL: "pkg:rpm/bind@9.11.13-3.el8?arch=src&epoch=32",
}, },
}, },
{ {
@@ -351,7 +351,7 @@ func Test_encodeSourcePackage(t *testing.T) {
}, },
}, },
expected: &cyclonedx.ExternalReference{ expected: &cyclonedx.ExternalReference{
Type: cyclonedx.ERTypeSourceDistribution, URL: "pkg:alpm/arch/gcc@13.2.1-3?arch=source&distro=arch-rolling", Type: cyclonedx.ERTypeSourceDistribution, URL: "pkg:alpm/arch/gcc@13.2.1-3?distro=arch-rolling",
}, },
}, },
{ {
@@ -371,7 +371,7 @@ func Test_encodeSourcePackage(t *testing.T) {
}, },
}, },
expected: &cyclonedx.ExternalReference{ expected: &cyclonedx.ExternalReference{
Type: cyclonedx.ERTypeSourceDistribution, URL: "pkg:alpm/arch/some-package@1.0.0?arch=source&distro=arch-rolling", Type: cyclonedx.ERTypeSourceDistribution, URL: "pkg:alpm/arch/some-package@1.0.0?distro=arch-rolling",
}, },
}, },
} }