Skip to content

[BUG] unexpected NoPropertiesProvidedException when deserializing empty OrganizationalEntity #764

Closed

Description

@Churro

After upgrading to cyclonedx-gradle-plugin 2.0.0 I noticed that it also adds an empty (and deprecated) manufacture object in the BOM metadata section that cyclonedx-python-lib is unable to parse:

Traceback (most recent call last):
  File "//main.py", line 11, in main
    bom = Bom.from_json(data=bom_data)
  File "/usr/local/lib/python3.13/site-packages/serializable/__init__.py", line 375, in from_json
    _data[k] = prop_info.concrete_type.from_json(data=v)
               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/serializable/__init__.py", line 375, in from_json
    _data[k] = prop_info.concrete_type.from_json(data=v)
               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/serializable/__init__.py", line 391, in from_json
    return cls(**_data)
  File "/usr/local/lib/python3.13/site-packages/cyclonedx/model/contact.py", line 300, in __init__
    raise NoPropertiesProvidedException(
        'One of name, urls or contacts must be supplied for an OrganizationalEntity - none supplied.'
    )
cyclonedx.exception.model.NoPropertiesProvidedException: One of name, urls or contacts must be supplied for an OrganizationalEntity - none supplied.

manufacture and manufacturer don't require any object attribute per CDX spec. An { } object is not "optional" OrganizationalEntity, so deserialization fails here:

if name is None and not urls and not contacts:
raise NoPropertiesProvidedException(
'One of name, urls or contacts must be supplied for an OrganizationalEntity - none supplied.'
)

Note that the deserialization issue can happen with any use of manufacture or manufacturer, regardless if in metadata or within a Component.

I'm not entirely sure where to best fix this, otherwise I'd open a PR myself 😊


Reproduction repo: https://github.com/Churro/cdx-manufacturer-bug

SBOM to deserialize:

{
  "bomFormat" : "CycloneDX",
  "specVersion" : "1.6",
  "version" : 1,
  "metadata" : {
    "timestamp" : "2025-01-25T19:11:26Z",
    "tools" : {
      "components" : [
        {
          "type" : "application",
          "author" : "CycloneDX",
          "name" : "cyclonedx-gradle-plugin",
          "version" : "2.0.0"
        }
      ],
      "services" : [ ]
    },
    "component" : {
      "type" : "application",
      "bom-ref" : "pkg:maven/foo/[email protected]",
      "name" : "foo-bar",
      "version" : "1.2.3",
      "purl" : "pkg:maven/foo/[email protected]",
      "modified" : false
    },
    "manufacture" : { },
    "licenses" : [ ]
  },
  "components" : [
    {
      "type" : "library",
      "name": "some-lib",    
      "manufacturer" : { }
    }
  ],
  "dependencies" : [ ]
}

Parsing code:

import json
import traceback

from cyclonedx.model.bom import Bom

def main() -> None:
    try:
        with open("repr.json", "r") as f:
            bom_data = json.load(f)
            bom = Bom.from_json(data=bom_data)
            print(bom)
    except BaseException as e:
        print(traceback.format_exc())

if __name__ == "__main__":
    main()

Activity

  1. jkowalleck commented on Jan 28, 2025

    @jkowalleck
    Member

    tested, report verified.
    I'll suggest to treat this as a defect/bug.

    a possible bug fix would be: Allow "empty" OrganizationalEntity.
    solution: OrganizationalEntity no longer throws NoPropertiesProvidedException.

    I'm not entirely sure where to best fix this, otherwise I'd open a PR myself 😊

    Feel free to pullrequest a solution.
    and please add your test data and test case similar to

    def test_regression_issue690(self) -> None:
    """
    regressio test for issue#690.
    see https://github.com/CycloneDX/cyclonedx-python-lib/issues/690
    """
    json_file = join(OWN_DATA_DIRECTORY, 'json',
    SchemaVersion.V1_6.to_version(),
    'issue690.json')
    with open(json_file) as f:
    json = json_loads(f.read())
    bom: Bom = Bom.from_json(json) # <<< is expected to not crash
    self.assertIsNotNone(bom)

  2. changed the title [-]NoPropertiesProvidedException for empty `manufacture` or `manufacturer` object[/-] [+]unexpected `NoPropertiesProvidedException` when deserializing empty `OrganizationalEntity`[/+] on Jan 28, 2025
  3. changed the title [-]unexpected `NoPropertiesProvidedException` when deserializing empty `OrganizationalEntity`[/-] [+][BUG] unexpected `NoPropertiesProvidedException` when deserializing empty `OrganizationalEntity`[/+] on Jan 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions