mirror of
https://gitlab.com/buildroot.org/buildroot.git
synced 2026-08-01 21:23:51 -09:00
utils/generate-cyclonedx: generate externalReferences with source-distribution
BSI TR-03183-2 5.4.2 [1] lists source code URIs under "Additional data fields for each component", and as such "MUST additionally be provided, if it exists". If a http or https source download URI is available from show-info, extract it and include it as an externalReference of type "source-distribution" in the CycloneDX output. [1] https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TR03183/BSI-TR-03183-2_v2_1_0.pdf?__blob=publicationFile&v=5 Signed-off-by: Martin Willi <martin@strongswan.org> Acked-by: Thomas Perale <thomas.perale@mind.be> Signed-off-by: Arnout Vandecappelle <arnout@rnout.be>
This commit is contained in:
committed by
Arnout Vandecappelle
parent
cc41cc3fcd
commit
e4f0fb126d
@@ -140,3 +140,29 @@ class TestGenerateCycloneDX(unittest.TestCase):
|
||||
|
||||
foo_deps = next(d for d in result["dependencies"] if d["ref"] == "package-foo")
|
||||
self.assertEqual(foo_deps["dependsOn"], ["package-bar", "skeleton-baz"])
|
||||
|
||||
def test_external_references(self):
|
||||
info = self._make_show_info()
|
||||
info["package-foo"]["downloads"] = [
|
||||
{
|
||||
"source": "foo-1.2.tar.gz",
|
||||
"uris": [
|
||||
"https+https://sources.buildroot.net/foo",
|
||||
"http|https+https://mirror.example.org/foo",
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
result = self._run_script(show_info=info)
|
||||
foo = self._find_component(result, "package-foo")
|
||||
|
||||
self.assertIn("externalReferences", foo)
|
||||
self.assertEqual(
|
||||
foo["externalReferences"],
|
||||
[
|
||||
{
|
||||
"type": "source-distribution",
|
||||
"url": "https://mirror.example.org/foo/foo-1.2.tar.gz",
|
||||
},
|
||||
],
|
||||
)
|
||||
|
||||
@@ -14,6 +14,8 @@ import gzip
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Iterator
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
import subprocess
|
||||
import sys
|
||||
@@ -261,6 +263,50 @@ def cyclonedx_patches(patch_list: list[str]):
|
||||
}
|
||||
|
||||
|
||||
def parse_uris(uris: list[str]) -> Iterator[tuple[list[str], str]]:
|
||||
"""Parse download URIs into (schemes, url) tuples.
|
||||
|
||||
Splits the Buildroot URI format "scheme[|scheme]+url" and yields all
|
||||
Buildroot schemes with the stripped URL, excluding
|
||||
sources.buildroot.net mirrors.
|
||||
|
||||
Args:
|
||||
uris (list): Array of URI strings from the show-info output.
|
||||
Yields:
|
||||
tuple[list[str], str]: (schemes, url) for each usable URI.
|
||||
"""
|
||||
for uri in uris:
|
||||
scheme, _, stripped_uri = uri.partition("+")
|
||||
if stripped_uri:
|
||||
parsed = urllib.parse.urlparse(stripped_uri)
|
||||
if parsed.hostname != "sources.buildroot.net":
|
||||
yield scheme.split("|"), stripped_uri
|
||||
|
||||
|
||||
def cyclonedx_external_refs(comp):
|
||||
"""Create CycloneDX external references for a component.
|
||||
|
||||
Args:
|
||||
comp (dict): The component information from the show-info output.
|
||||
Returns:
|
||||
dict: External reference information in CycloneDX format, or empty dict
|
||||
"""
|
||||
SOURCE_DIST_SCHEMES = {"http", "https"}
|
||||
|
||||
refs = []
|
||||
for download in comp.get("downloads", []):
|
||||
source = download.get("source")
|
||||
for schemes, uri in parse_uris(download.get("uris", [])):
|
||||
if set(schemes) & SOURCE_DIST_SCHEMES and source:
|
||||
refs.append({
|
||||
"type": "source-distribution",
|
||||
"url": f"{uri}/{source}",
|
||||
})
|
||||
if refs:
|
||||
return {"externalReferences": refs}
|
||||
return {}
|
||||
|
||||
|
||||
def cyclonedx_component(name, comp):
|
||||
"""Translate a component from the show-info output, to a component entry in CycloneDX format.
|
||||
|
||||
@@ -284,6 +330,7 @@ def cyclonedx_component(name, comp):
|
||||
**({
|
||||
"cpe": comp["cpe-id"],
|
||||
} if "cpe-id" in comp else {}),
|
||||
**cyclonedx_external_refs(comp),
|
||||
**(cyclonedx_patches(comp["patches"]) if comp.get("patches") else {}),
|
||||
"properties": [{
|
||||
"name": "BR_TYPE",
|
||||
|
||||
Reference in New Issue
Block a user