Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ v35.4.0 (unreleased)
- Add a Resources tree view.
https://github.com/aboutcode-org/scancode.io/issues/1682

- Improve CycloneDX SBOM support.
* Upgrade the cyclonedx-python-lib to 11.0.0
* Fix the validate_document following library upgrade.
* Add support when the "components" entry is missing.
https://github.com/aboutcode-org/scancode.io/issues/1727

v35.3.0 (2025-08-20)
--------------------

Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ dependencies = [
# Profiling
"pyinstrument==5.1.1",
# CycloneDX
"cyclonedx-python-lib==10.2.0",
"jsonschema==4.24.0",
"cyclonedx-python-lib==11.0.0",
"jsonschema==4.25.1",
# MatchCode-toolkit
"matchcode-toolkit==7.2.2",
# Univers
Expand Down
8 changes: 6 additions & 2 deletions scanpipe/pipes/cyclonedx.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,10 @@ def validate_document(document):
The validator is loaded from the document specVersion property.
"""
if isinstance(document, str):
document_str = document
document = json.loads(document)
else:
document_str = json.dumps(document)

spec_version = document.get("specVersion")
if not spec_version:
Expand All @@ -132,7 +135,8 @@ def validate_document(document):
schema_version = SchemaVersion.from_version(spec_version)

json_validator = JsonStrictValidator(schema_version)
return json_validator._validata_data(document)
json_validation_errors = json_validator.validate_str(document_str)
return json_validation_errors


def is_cyclonedx_bom(input_location):
Expand Down Expand Up @@ -281,7 +285,7 @@ def is_empty(value):
elif isinstance(value, list) and not any(value):
return True

for component in cyclonedx_document_json["components"]:
for component in cyclonedx_document_json.get("components", []):
for property_name, property_value in component.items():
if is_empty(property_value) or property_name in ignored_properties:
entries_to_delete.append((component, property_name))
Expand Down
21 changes: 21 additions & 0 deletions scanpipe/tests/data/cyclonedx/missing_components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"serialNumber": "urn:uuid:b74fe5df-e965-415e-ba65-f38421a0695d",
"version": 1,
"metadata": {
"component": {
"bom-ref": "804c3391-e6f9-415f-bb7a-cb6653853a46",
"name": "name",
"type": "library"
},
"timestamp": "2024-03-07T17:05:37.329061+00:00",
"tools": [
{
"name": "ScanCode.io",
"version": "0.0.0"
}
]
}
}
5 changes: 5 additions & 0 deletions scanpipe/tests/pipes/test_cyclonedx.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,11 @@ def test_scanpipe_cyclonedx_resolve_cyclonedx_packages_pre_validation(self):
expected = [{"name": "asgiref", "package_uid": "pkg:pypi/[email protected]"}]
self.assertEqual(expected, package_data)

def test_scanpipe_cyclonedx_resolve_cyclonedx_packages_missing_components(self):
input_location = self.data / "missing_components.json"
package_data = cyclonedx.resolve_cyclonedx_packages(input_location)
self.assertEqual([], package_data)

def test_scanpipe_cyclonedx_cleanup_components_properties(self):
cyclonedx_document_json = {
"components": [
Expand Down