Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ParseException with ancestors in the metadata section (XML SBOM) #363

Open
dmeibusch opened this issue Jan 11, 2024 · 0 comments
Open

ParseException with ancestors in the metadata section (XML SBOM) #363

dmeibusch opened this issue Jan 11, 2024 · 0 comments

Comments

@dmeibusch
Copy link
Contributor

dmeibusch commented Jan 11, 2024

Affected version: 8.0.3 and possible earlier 8.x.

Sample SBOM that fails to parse.

<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.2"
     serialNumber="urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79"
     version="1">
  <metadata>
    <component type="library">
      <group>com.acme</group>
      <name>sample-library</name>
      <version>1.0.0</version>
      <pedigree>
        <ancestors>
          <component type="library">
            <group>org.example</group>
            <name>sample-library-ancestor</name>
            <version>1.0.0</version>
          </component>
        </ancestors>
        <descendants>
          <component type="library">
            <group>org.example</group>
            <name>sample-library-descendant</name>
            <version>1.0.1</version>
          </component>
        </descendants>
        <variants>
          <component type="library">
            <group>org.example</group>
            <name>sample-library-variant</name>
            <version>1.0.2</version>
          </component>
        </variants>
      </pedigree>
    </component>
  </metadata>
</bom>

Exception:

org.cyclonedx.exception.ParseException: com.fasterxml.jackson.databind.JsonMappingException: Cannot deserialize value of type `[Lorg.cyclonedx.model.Component;` from Object value (token `JsonToken.START_OBJECT`)
 at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: org.cyclonedx.model.Component["pedigree"]->org.cyclonedx.model.Pedigree["ancestors"]) (through reference chain: org.cyclonedx.model.Bom["metadata"])

	at org.cyclonedx.parsers.XmlParser.parse(XmlParser.java:89)
	at org.cyclonedx.parsers.XmlParserTest.testValid12BomWithMetadataPedigree(XmlParserTest.java:135)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Cannot deserialize value of type `[Lorg.cyclonedx.model.Component;` from Object value (token `JsonToken.START_OBJECT`)
 at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: org.cyclonedx.model.Component["pedigree"]->org.cyclonedx.model.Pedigree["ancestors"]) (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:1853)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:316)
	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:91)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4825)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3833)
	at org.cyclonedx.parsers.XmlParser.parse(XmlParser.java:87)
	... 4 more
Caused by: java.lang.IllegalArgumentException: Cannot deserialize value of type `[Lorg.cyclonedx.model.Component;` from Object value (token `JsonToken.START_OBJECT`)
 at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: org.cyclonedx.model.Component["pedigree"]->org.cyclonedx.model.Pedigree["ancestors"])
	at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:4544)
	at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:4475)
	at org.cyclonedx.util.deserializer.MetadataDeserializer.deserialize(MetadataDeserializer.java:53)
	at org.cyclonedx.util.deserializer.MetadataDeserializer.deserialize(MetadataDeserializer.java:28)
	at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:314)
	... 10 more
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `[Lorg.cyclonedx.model.Component;` from Object value (token `JsonToken.START_OBJECT`)
 at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: org.cyclonedx.model.Component["pedigree"]->org.cyclonedx.model.Pedigree["ancestors"])
	at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
	at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1752)
	at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1526)
	at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1473)
	at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.handleNonArray(ObjectArrayDeserializer.java:345)
	at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:197)
	at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:27)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323)
	at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:4801)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2974)
	at com.fasterxml.jackson.core.JsonParser.readValueAs(JsonParser.java:2363)
	at org.cyclonedx.util.deserializer.ComponentWrapperDeserializer.deserialize(ComponentWrapperDeserializer.java:75)
	at org.cyclonedx.util.deserializer.ComponentWrapperDeserializer.deserialize(ComponentWrapperDeserializer.java:34)
	at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:314)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
	at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:314)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
	at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:4539)
	... 15 more

The library has special deserialization code to handle component elements within ancestors (and a few other cases).
See org.cyclonedx.util.deserializer.ComponentWrapperDeserializer.

A change in the library or perhaps in Jackson has changed the type of the parser such that it is no longer an instance of FromXmlParser when this code is reached (it is now an internal Jackson token buffer parser class instance).

    final String location = parser.getCurrentName();
    if (parser instanceof FromXmlParser) {
      switch (location) {
        case ANCESTORS:
          return parser.readValueAs(Ancestors.class);
        case DESCENDANTS:
          return parser.readValueAs(Descendants.class);
        case VARIANTS:
          return parser.readValueAs(Variants.class);
        default:
          return null;
      }
    }

Hence the alternate branch assuming JSON parsing is taken, which fails since the component encountered is an Object not an Array of Objects.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant