Skip to content

Commit 4e79e59

Browse files
committed
rework tools xml deserializer
Signed-off-by: Jan Kowalleck <[email protected]>
1 parent b0260a7 commit 4e79e59

File tree

3 files changed

+16
-34
lines changed

3 files changed

+16
-34
lines changed

cyclonedx/model/tool.py

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
from sortedcontainers import SortedSet
2727

2828
from .._internal.compare import ComparableTuple as _ComparableTuple
29-
from ..exception.serialization import CycloneDxDeserializationException
3029
from ..schema import SchemaVersion
3130
from ..schema.schema import SchemaVersion1Dot4, SchemaVersion1Dot5, SchemaVersion1Dot6
3231
from . import ExternalReference, HashType, _HashTypeRepositorySerializationHelper
@@ -308,7 +307,8 @@ def json_denormalize(cls, o: Union[List[Dict[str, Any]], Dict[str, Any]],
308307
services = map(lambda s: Service.from_json( # type:ignore[attr-defined]
309308
s), o.get('services', ()))
310309
elif isinstance(o, Iterable):
311-
tools = map(lambda t: Tool.from_json(t), o) # type:ignore[attr-defined]
310+
tools = map(lambda t: Tool.from_json( # type:ignore[attr-defined]
311+
t), o)
312312
return ToolRepository(components=components, services=services, tools=tools)
313313

314314
@classmethod
@@ -349,23 +349,19 @@ def xml_denormalize(cls, o: Element, *,
349349
prop_info: 'ObjectMetadataLibrary.SerializableProperty',
350350
ctx: Type[Any],
351351
**kwargs: Any) -> ToolRepository:
352-
tools = []
352+
ns_map = {'bom': default_ns or ''}
353+
# Do not iterate over `o` and do not check for expected `.tag` of items.
354+
# This check could have been done by schema validators before even deserializing.
355+
tools = None
353356
components = None
354357
services = None
355-
for e in o:
356-
tag = e.tag if default_ns is None else e.tag.replace(f'{{{default_ns}}}', '')
357-
if tag == 'tool':
358-
tools.append(Tool.from_xml( # type:ignore[attr-defined]
359-
e, default_ns))
360-
elif tag == 'components':
361-
components = map(lambda s: Component.from_xml( # type:ignore[attr-defined]
362-
s, default_ns), e)
363-
elif tag == 'services':
364-
services = map(lambda s: Service.from_xml( # type:ignore[attr-defined]
365-
s, default_ns), e)
366-
else:
367-
raise CycloneDxDeserializationException(f'unexpected: {e!r}')
368-
return ToolRepository(
369-
tools=tools,
370-
components=components,
371-
services=services)
358+
ts = o.findall('bom:tool', ns_map)
359+
if len(ts) > 0:
360+
tools = map(lambda t: Tool.from_xml( # type:ignore[attr-defined]
361+
t, default_ns), ts)
362+
else:
363+
components = map(lambda c: Component.from_xml( # type:ignore[attr-defined]
364+
c, default_ns), o.iterfind('./bom:components/bom:component', ns_map))
365+
services = map(lambda s: Service.from_xml( # type:ignore[attr-defined]
366+
s, default_ns), o.iterfind('./bom:services/bom:service', ns_map))
367+
return ToolRepository(components=components, services=services, tools=tools)

tests/_data/own/xml/1.5/invalid-tool.xml

Lines changed: 0 additions & 8 deletions
This file was deleted.

tests/test_deserialize_xml.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,3 @@ def test_prepared(self, get_bom: Callable[[], Bom], *_: Any, **__: Any) -> None:
4646
bom = Bom.from_xml(s)
4747
self.assertBomDeepEqual(expected, bom,
4848
fuzzy_deps=get_bom in all_get_bom_funct_with_incomplete_deps)
49-
50-
def test_unexpected_toolrepository_item(self) -> None:
51-
with open(join(OWN_DATA_DIRECTORY, 'xml', '1.5', 'invalid-tool.xml')) as input_xml:
52-
with self.assertRaisesRegex(CycloneDxDeserializationException,
53-
r"^unexpected: <Element '{.+?}foo' at 0x[0-9a-fA-F]+>$"):
54-
Bom.from_xml(input_xml)

0 commit comments

Comments
 (0)