Skip to content

Conversation

qkaiser
Copy link
Contributor

@qkaiser qkaiser commented Oct 20, 2025

The identity field in ComponentEvidence can be either a single object (dict) in CycloneDX 1.5 or a single object/array of objects in CycloneDX 1.6. The previous implementation failed when deserializing a single object format, throwing 'str' object has no attribute 'items' error.

Added _IdentitySetSerializationHelper to properly handle both formats:

  • json_normalize: serializes Identity objects as list while preserving view context
  • json_deserialize: handles both dict (single) and list (array) formats

Also updated _ComponentEvidenceSerializationHelper.json_denormalize to normalize single dict format to array before deserialization for consistency.

Fixes deserialization of CycloneDX 1.5 and 1.6 SBOMs with component evidence.

The exact error being raised is the following:

AttributeError: There was an AttributeError deserializing JSON to <class 'cyclonedx.model.component.Component'>
the Property <s.oml.SerializableProperty name=evidence, custom_names={}, array=False, enum=False, optional=True, c_type=<class 'cyclonedx.model.component_evidence.ComponentEvidence'>,
type=typing.Optional[cyclonedx.model.component_evidence.ComponentEvidence],
custom_type=<class 'cyclonedx.model.component_evidence._ComponentEvidenceSerializationHelper'>,
xml_attr=False, xml_sequence=24>:
There was an AttributeError deserializing JSON to
<class 'cyclonedx.model.component_evidence.ComponentEvidence'>
the Property <s.oml.SerializableProperty name=identity, custom_names={}, array=True, enum=False, optional=False, c_type=<class 'cyclonedx.model.component_evidence.Identity'>,
type=typing.Set[cyclonedx.model.component_evidence.Identity],
custom_type=None, xml_attr=False, xml_sequence=1>: 'str' object has no attribute 'items'

Which gets triggered when calling Bom.from_json() containing entries like this one:

{
      "type": "library",
      "bom-ref": "pkg:npm/bcryptjs@2.4.3",
      "group": "",
      "name": "bcryptjs",
      "version": "2.4.3",
      "scope": "required",
// --snip--
      "evidence": {
        "identity": {
          "field": "purl",
          "confidence": 1,
          "concludedValue": "package-lock.json",
          "methods": [
            {
              "technique": "manifest-analysis",
              "confidence": 1,
              "value": "package-lock.json"
            }
          ]
        },
      },
    },

…rialization

The identity field in ComponentEvidence can be either a single object (dict)
in CycloneDX 1.5 or a single object/array of objects in CycloneDX 1.6.
The previous implementation failed when deserializing a single object format,
throwing 'str' object has no attribute 'items' error.

Added _IdentitySetSerializationHelper to properly handle both formats:
- json_normalize: serializes Identity objects as list while preserving view context
- json_deserialize: handles both dict (single) and list (array) formats

Also updated _ComponentEvidenceSerializationHelper.json_denormalize to normalize
single dict format to array before deserialization for consistency.

Fixes deserialization of CycloneDX 1.5 and 1.6 SBOMs with component evidence.

Signed-off-by: Quentin Kaiser <quentin.kaiser@onekey.com>
@qkaiser qkaiser requested a review from a team as a code owner October 20, 2025 10:00
@jkowalleck jkowalleck changed the title fix: handle identity field as dict or array in ComponentEvidence deserialization feat!: multiple ComponentEvidence.identity Oct 21, 2025
@jkowalleck jkowalleck changed the title feat!: multiple ComponentEvidence.identity feat: deserialize single ComponentEvidence.identity Oct 21, 2025
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
… into fix/component-evidence-identity-deserialization

- remove JSON-only implemntations and tests
- added more tests
- streamlined some imeplementations

Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
@jkowalleck
Copy link
Member

Altered the patch, and added new tests for deserialization.
You will find that this is working as intended.

please review the chages, @qkaiser

Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
@jkowalleck jkowalleck added the enhancement New feature or request label Oct 21, 2025
Copy link
Contributor Author

@qkaiser qkaiser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modifications to the initial patch looks ok to me.

@jkowalleck jkowalleck merged commit 9425c67 into CycloneDX:main Oct 22, 2025
49 checks passed
@jkowalleck
Copy link
Member

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants