CycloneDX / cyclonedx-core-java

CycloneDX SBOM Model and Utils for Creating and Validating BOMs
https://cyclonedx.org/
Apache License 2.0
81 stars 59 forks source link

ParseException with nested components in the metadata section (XML SBoM) #447

Open empwilli opened 2 months ago

empwilli commented 2 months ago

Affected version: 9.0.4. OS: Linux

Minimal example:

<?xml version="1.0" encoding="utf-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.3" serialNumber="urn:uuid:173bebbd-0cea-401f-ae32-49e0ccebf575" version="1">
    <metadata>
        <component type="application" bom-ref="path+file:///home/user/some/local/dep#0.0.1">
            <name>omnect-cli</name>
            <components>
                <component type="library" bom-ref="path+file:///home/user/some/local/dep#0.0.2">
                    <name>dep</name>
                    <version>0.0.2</version>
                </component>
            </components>
        </component>
    </metadata>
</bom>

Exception:

org.cyclonedx.exception.ParseException: com.fasterxml.jackson.databind.JsonMappingException: Cannot deserialize value of type `java.util.ArrayList<org.cyclonedx.model.Component>` from Object value (token `JsonToken.START_OBJECT`)
 at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: org.cyclonedx.model.Component["components"]) (through reference chain: org.cyclonedx.model.Bom["metadata"])
    at org.cyclonedx.parsers.XmlParser.parse(XmlParser.java:101)
    at de.conplement.App.getXmlBom(App.java:23)
    at de.conplement.App.main(App.java:29)
    at org.codehaus.mojo.exec.ExecJavaMojo.doMain(ExecJavaMojo.java:385)
    at org.codehaus.mojo.exec.ExecJavaMojo.doExec(ExecJavaMojo.java:374)
    at org.codehaus.mojo.exec.ExecJavaMojo.lambda$execute$0(ExecJavaMojo.java:296)
    at java.lang.Thread.run(Thread.java:750)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Cannot deserialize value of type `java.util.ArrayList<org.cyclonedx.model.Component>` from Object value (token `JsonToken.START_OBJECT`)
 at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: org.cyclonedx.model.Component["components"]) (through reference chain: org.cyclonedx.model.Bom["metadata"])
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:402)
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:361)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.wrapAndThrow(BeanDeserializerBase.java:1937)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:312)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
    at com.fasterxml.jackson.dataformat.xml.deser.WrapperHandlingDeserializer.deserialize(WrapperHandlingDeserializer.java:122)
    at com.fasterxml.jackson.dataformat.xml.deser.XmlDeserializationContext.readRootValue(XmlDeserializationContext.java:104)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4905)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3909)
    at org.cyclonedx.parsers.XmlParser.parse(XmlParser.java:99)
    ... 6 more
Caused by: java.lang.IllegalArgumentException: Cannot deserialize value of type `java.util.ArrayList<org.cyclonedx.model.Component>` from Object value (token `JsonToken.START_OBJECT`)
 at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: org.cyclonedx.model.Component["components"])
    at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:4624)
    at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:4555)
    at org.cyclonedx.util.deserializer.MetadataDeserializer.deserialize(MetadataDeserializer.java:53)
    at org.cyclonedx.util.deserializer.MetadataDeserializer.deserialize(MetadataDeserializer.java:29)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:310)
    ... 12 more
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.util.ArrayList<org.cyclonedx.model.Component>` from Object value (token `JsonToken.START_OBJECT`)
 at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: org.cyclonedx.model.Component["components"])
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1767)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1541)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1488)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.handleNonArray(CollectionDeserializer.java:402)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:254)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:30)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:310)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
    at com.fasterxml.jackson.dataformat.xml.deser.WrapperHandlingDeserializer.deserialize(WrapperHandlingDeserializer.java:122)
    at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:4619)
    ... 17 more

If we have no nested components, the SBoM can be parsed, i.e., the following works:

<?xml version="1.0" encoding="utf-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.3" serialNumber="urn:uuid:173bebbd-0cea-401f-ae32-49e0ccebf575" version="1">
    <metadata>
        <component type="application" bom-ref="path+file:///home/user/some/local/dep#0.0.1">
            <name>omnect-cli</name>
            <components></components>
        </component>
    </metadata>
</bom>