Skip to content

Merging objects with non-unique bom_refs silently introduces data inconsistency #807

Description

@wkoot

NB: this is an extension of #540 and #677

Given the testdata in #677, set up a test for #540 but with clashing bom_refs and unique names instead:

>>> from json import load
>>> from cyclonedx.model.bom import Bom
>>> from cyclonedx.model.component import Component, ComponentType
>>> root_component = Component(
...     type=ComponentType.FRAMEWORK,
...     name="root 42",
...     version="42",
...     bom_ref="root",
... )
>>>
>>> bom = Bom()
>>> bom.metadata.component = root_component
>>> bom.validate()
True
>>> len(bom.components)
0
>>> len(bom.dependencies)
1
>>>
>>> with open('out.json', mode="r") as testfile:
...  json_bom = load(testfile)
...
>>> len(json_bom['components'])
4
>>> len(json_bom['dependencies'])
3
>>>
>>> loaded_bom = Bom.from_json(json_bom)
>>> loaded_bom.validate()
True
>>> len(loaded_bom.components)
4
>>> len(loaded_bom.dependencies)
5
>>>
>>> loaded_bom.metadata.component
<Component bom-ref=<BomRef 'root' id=139844009673936>, group=None, name=test, version=None, type=ComponentType.APPLICATION>
>>> bom.metadata.component
<Component bom-ref=<BomRef 'root' id=139844025859088>, group=None, name=root 42, version=42, type=ComponentType.FRAMEWORK>
>>>
>>> loaded_bom.metadata.component.bom_ref
<BomRef 'root' id=139844009673936>
>>> bom.metadata.component.bom_ref
<BomRef 'root' id=139844025859088>
>>>
>>> bom.metadata.component.bom_ref == loaded_bom.metadata.component.bom_ref
True
>>> loaded_bom.metadata.component == bom.metadata.component
False
>>>
>>> bom.components.add(loaded_bom.metadata.component)
>>> bom.register_dependency(root_component, [loaded_bom.metadata.component])
>>> bom.components |= loaded_bom.components
>>> bom.dependencies |= loaded_bom.dependencies
>>>
>>> bom.validate()
True
>>>
>>> len(bom.components)
5
>>> len(bom.dependencies)
6

Note that the Bom says it is valid, while it is actually not - although this is not apparent at a glance.
When outputting to json (e.g. with the reported JsonV1Dot5), dependencies is shown to be as follows:

        [
            {"ref": "root", "dependsOn": ["BomRef.23942051401152453.4412489734431171"]},
            {"ref": "root", "dependsOn": ["test11", "test21"]},
            {"ref": "test11", "dependsOn": ["test12"]},
            {"ref": "test12"},
            {"ref": "test21", "dependsOn": ["test22"]},
            {"ref": "test22"}
        ]

This is actually invalid and would not validate when dumped to file and re-read by the library

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions