Skip to content

Commit f08a656

Browse files
authored
fix: prevent errors on metadata handling for some specification versions (#330)
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com> Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
1 parent 493104c commit f08a656

File tree

2 files changed

+49
-46
lines changed

2 files changed

+49
-46
lines changed

cyclonedx/output/json.py

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -97,44 +97,43 @@ def generate(self, force_regeneration: bool = False) -> None:
9797
self.generated = True
9898

9999
def _specialise_output_for_schema_version(self, bom_json: Dict[Any, Any]) -> str:
100-
if not self.bom_supports_metadata():
101-
if 'metadata' in bom_json.keys():
100+
if 'metadata' in bom_json.keys():
101+
if not self.bom_supports_metadata():
102102
del bom_json['metadata']
103+
else:
104+
if 'tools' in bom_json['metadata'].keys():
105+
if not self.bom_metadata_supports_tools():
106+
del bom_json['metadata']['tools']
107+
else:
108+
if not self.bom_metadata_supports_tools_external_references():
109+
for _tool in bom_json['metadata']['tools']:
110+
if 'externalReferences' in _tool.keys():
111+
del _tool['externalReferences']
112+
del _tool
113+
if 'licenses' in bom_json['metadata'].keys() and not self.bom_metadata_supports_licenses():
114+
del bom_json['metadata']['licenses']
115+
if 'properties' in bom_json['metadata'].keys() and not self.bom_metadata_supports_properties():
116+
del bom_json['metadata']['properties']
117+
118+
if self.get_bom().metadata.component:
119+
bom_json['metadata'] = self._recurse_specialise_component(bom_json['metadata'], 'component')
120+
121+
bom_json = self._recurse_specialise_component(bom_json)
103122

104-
if not self.bom_metadata_supports_tools():
105-
del bom_json['metadata']['tools']
106-
elif not self.bom_metadata_supports_tools_external_references():
107-
for i in range(len(bom_json['metadata']['tools'])):
108-
if 'externalReferences' in bom_json['metadata']['tools'][i].keys():
109-
del bom_json['metadata']['tools'][i]['externalReferences']
110-
111-
if not self.bom_metadata_supports_licenses() and 'licenses' in bom_json['metadata'].keys():
112-
del bom_json['metadata']['licenses']
113-
114-
if not self.bom_metadata_supports_properties() and 'properties' in bom_json['metadata'].keys():
115-
del bom_json['metadata']['properties']
116-
117-
# Iterate Components
118-
if self.get_bom().metadata.component:
119-
bom_json['metadata'] = self._recurse_specialise_component(bom_json=bom_json['metadata'],
120-
base_key='component')
121-
bom_json = self._recurse_specialise_component(bom_json=bom_json)
122-
123-
# Iterate Services
124123
if 'services' in bom_json.keys():
125-
for i in range(len(bom_json['services'])):
126-
if not self.services_supports_properties() and 'properties' in bom_json['services'][i].keys():
127-
del bom_json['services'][i]['properties']
128-
129-
if not self.services_supports_release_notes() and 'releaseNotes' in bom_json['services'][i].keys():
130-
del bom_json['services'][i]['releaseNotes']
124+
for _service in bom_json['services']:
125+
if 'properties' in _service.keys() and not self.services_supports_properties():
126+
del _service['properties']
127+
if 'releaseNotes' in _service.keys() and not self.services_supports_release_notes():
128+
del _service['releaseNotes']
129+
del _service
131130

132-
# Iterate externalReferences
133131
if 'externalReferences' in bom_json.keys():
134-
for i in range(len(bom_json['externalReferences'])):
135-
if not self.external_references_supports_hashes() \
136-
and 'hashes' in bom_json['externalReferences'][i].keys():
137-
del bom_json['externalReferences'][i]['hashes']
132+
if not self.external_references_supports_hashes():
133+
for _externalReference in bom_json['externalReferences']:
134+
if 'hashes' in _externalReference.keys():
135+
del _externalReference['hashes']
136+
del _externalReference
138137

139138
return json.dumps(bom_json)
140139

tests/base.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -87,27 +87,31 @@ def assertEqualJsonBom(self, a: str, b: str) -> None:
8787
"""
8888
Remove UUID before comparison as this will be unique to each generation
8989
"""
90-
ab, bb = json.loads(a), json.loads(b)
90+
ab = json.loads(a)
91+
bb = json.loads(b)
9192

9293
# Null serialNumbers
9394
ab['serialNumber'] = single_uuid
9495
bb['serialNumber'] = single_uuid
9596

9697
# Unify timestamps to ensure they will compare
9798
now = datetime.now(tz=timezone.utc)
98-
ab['metadata']['timestamp'] = now.isoformat()
99-
bb['metadata']['timestamp'] = now.isoformat()
10099

101-
# Align 'this' Tool Version
102-
if 'tools' in ab['metadata'].keys():
103-
for i, tool in enumerate(ab['metadata']['tools']):
104-
if tool['name'] == cyclonedx_lib_name:
105-
ab['metadata']['tools'][i]['version'] = cyclonedx_lib_version
106-
107-
if 'tools' in bb['metadata'].keys():
108-
for i, tool in enumerate(bb['metadata']['tools']):
109-
if tool['name'] == cyclonedx_lib_name:
110-
bb['metadata']['tools'][i]['version'] = cyclonedx_lib_version
100+
if 'metadata' in ab.keys():
101+
ab['metadata']['timestamp'] = now.isoformat()
102+
if 'tools' in ab['metadata'].keys():
103+
for tool in ab['metadata']['tools']:
104+
if tool['name'] == cyclonedx_lib_name:
105+
tool['version'] = cyclonedx_lib_version
106+
del tool
107+
108+
if 'metadata' in bb.keys():
109+
bb['metadata']['timestamp'] = now.isoformat()
110+
if 'tools' in bb['metadata'].keys():
111+
for tool in bb['metadata']['tools']:
112+
if tool['name'] == cyclonedx_lib_name:
113+
tool['version'] = cyclonedx_lib_version
114+
del tool
111115

112116
self.assertEqualJson(json.dumps(ab), json.dumps(bb))
113117

0 commit comments

Comments
 (0)