FasterXML / jackson-dataformats-binary

Uber-project for standard Jackson binary format backends: avro, cbor, ion, protobuf, smile
Apache License 2.0
310 stars 133 forks source link

Unexpected `MismatchedInputException` for `byte[]` value bound to `String` in collection/array #188

Closed quaff closed 4 years ago

quaff commented 4 years ago

I'm trying deserialize WebAuthn attestation which is encoded with cbor format, I find a strange error, It cannot be deserialized to target type, but can be deserialized to JsonNode then deserialize to target type. here is example project cbor.zip. code snippet:

    @Test
    public void test() throws Exception {
        Attestation attestation = om.readValue(source, Attestation.class); // exception raised
        assertEquals("fido-u2f", attestation.getFmt());
    }

    @Test
    public void testWorkAround() throws Exception {
        Attestation attestation = om.readValue(om.treeAsTokens(om.readValue(source, JsonNode.class)),
                Attestation.class);
        assertEquals("fido-u2f", attestation.getFmt());
    }
cowtowncoder commented 4 years ago

Interesting: value of x5c is declared as List<String> in POJO, but I think it is encoded as List<byte[]>. That is, elements contain binary data, not Strings. And there is no default deserialization from binary data into String.

But in case of reading as tree, BinaryNode can apparently be read as text -- getText() will coerce value into Base64 encoded String.

Now.... at this point, it'd be unclear if this is a bug. But looking at difference between StringDeserializer (used for "simple" String valued properties), it too does actually allow exposing Binary data as Base64-encoded String. Whereas StringCollectionDeserializer does not. Same problem would occur with StringArrayDeserializer, as both ultimate delegate to _parseString() method of StdDeserializer.

So. I think this qualifies as a bug, but one that can only affect formats that have native binary data type. I'll file a bug in databind and hopefully fix it.

In the meantime I would probably suggest mapping value as List<byte[]> instead of List<String> to better match actual contents.

quaff commented 4 years ago

I confirm https://github.com/FasterXML/jackson-databind/commit/df34f86158476d68b3fc7c67c4d901a1bfaa5950 fixed this.

cowtowncoder commented 4 years ago

Thank you @quaff!