cyclonedx-cli icon indicating copy to clipboard operation
cyclonedx-cli copied to clipboard

Hierarchical merge misplaces <properties> nodes of toplevel components

Open schlenk opened this issue 2 years ago • 1 comments

Problem

I try to merge a SBOM created via https://github.com/CycloneDX/cyclonedx-node-npm to another SBOM.

The NPM SBOM contains extra properties for the toplevel components and subcomponents e.g. it looks like this, which is valid.:

  <components>
    <component type="library" bom-ref="@cyclonedx/[email protected]">
      <author>Jan Kowalleck</author>
      <group>@cyclonedx</group>
      <name>cyclonedx-npm</name>
      <version>1.7.2</version>
      <description>Create CycloneDX Software Bill of Materials (SBOM) from NPM projects.</description>
      <licenses>
        <license>
          <id>Apache-2.0</id>
        </license>
      </licenses>
      <purl>pkg:npm/%40cyclonedx/[email protected]?vcs_url=git+https://github.com/CycloneDX/cyclonedx-node-npm.git</purl>
      <externalReferences>
         ...
      </externalReferences>
      <properties>
        <property name="cdx:npm:package:extraneous">true</property>
        <property name="cdx:npm:package:path">node_modules/@cyclonedx\cyclonedx-npm</property>
      </properties>
      <components>
           ...

But after i do a hierarchical merge, the properties get shifted to the wrong place in the xsd:sequence, behind the "components" element, but the XSD wants them to be in front.

     <components>
        <component type="library" bom-ref="[email protected]:@cyclonedx/[email protected]">
          <author>Jan Kowalleck</author>
          <group>@cyclonedx</group>
          <name>cyclonedx-npm</name>
          <version>1.7.2</version>
          <description>Create CycloneDX Software Bill of Materials (SBOM) from NPM projects.</description>
          <licenses>
            <license>
              <id>Apache-2.0</id>
            </license>
          </licenses>
          <purl>pkg:npm/%40cyclonedx/[email protected]?vcs_url=git+https://github.com/CycloneDX/cyclonedx-node-npm.git</purl>
          <externalReferences>
            <reference type="issue-tracker">
              <url>https://github.com/CycloneDX/cyclonedx-node-npm/issues</url>
              <comment>as detected from PackageJson property "bugs.url"</comment>
            </reference>
            <reference type="vcs">
              <url>git+https://github.com/CycloneDX/cyclonedx-node-npm.git</url>
              <comment>as detected from PackageJson property "repository.url"</comment>
            </reference>
            <reference type="website">
              <url>https://github.com/CycloneDX/cyclonedx-node-npm#readme</url>
              <comment>as detected from PackageJson property "homepage"</comment>
            </reference>
          </externalReferences>
          <components>
          ...
          </components>
          <properties>
            <property name="cdx:npm:package:extraneous">true</property>
            <property name="cdx:npm:package:path">node_modules/@cyclonedx\cyclonedx-npm</property>
          </properties>
        </component>

This leads to a validation error later:

 Validating XML BOM...
Validation failed at line number 4304 and position 12: The element 'component' in namespace 'http://cyclonedx.org/schema/bom/1.4' has invalid child element 'properties' in namespace 'http://cyclonedx.org/schema/bom/1.4'. List of possible elements expected: 'evidence, releaseNotes' in namespace 'http://cyclonedx.org/schema/bom/1.4' as well as any element in namespace '##other'.
BOM is not valid.

cyclonedx-cli version

Running on Windows 10 with the prebuilt binaries.

cyclonedx-cli --version
0.24.2

Reproduction

Try to merge the two attached files from the ZIP (one created by cyclonedx-npm, one from the example repo): property_merge.zip

cyclonedx-cli merge --hierarchical --name propexample --version 1.0 --output-file bom.xml --input-files example1.cdx.xml proton-bridge-v1.8.0.bom.xml
Processing input file example1.cdx.xml
    Contains 5 components
Processing input file proton-bridge-v1.8.0.bom.xml
    Contains 201 components
Writing output file...
    Total 2 components

cyclonedx-cli validate --input-file bom.xml --fail-on-errors --input-version v1_4
Validating XML BOM...
Validation failed at line number 432 and position 12: The element 'component' in namespace 'http://cyclonedx.org/schema/bom/1.4' has invalid child element 'properties' in namespace 'http://cyclonedx.org/schema/bom/1.4'. List of possible elements expected: 'evidence, releaseNotes' in namespace 'http://cyclonedx.org/schema/bom/1.4' as well as any element in namespace '##other'.
BOM is not valid.

schlenk avatar Feb 01 '23 15:02 schlenk

As far as I can see, one could either swap the Properties and Components member here: https://github.com/CycloneDX/cyclonedx-dotnet-library/blob/b6790529c1da67f98ae63fba47a444a80ceae24a/src/CycloneDX.Core/Models/Component.cs#L181-L189 or one could use the Order argument in all XmlArray and XmlElement in the Component class to correct the order. By default, XmlSerialization seems to use the order in which the items are defined, compare also https://learn.microsoft.com/en-us/dotnet/api/system.xml.serialization.xmlelementattribute.order?view=net-6.0#system-xml-serialization-xmlelementattribute-order

andreas-hilti avatar Apr 22 '23 14:04 andreas-hilti

Should be fixed in 0.25.1

mtsfoni avatar May 22 '24 19:05 mtsfoni