-
Notifications
You must be signed in to change notification settings - Fork 642
CBOR serializer encodes null class instance as empty map instead of null #2848
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
Can you please provide an example of serializable class and expected/actual output? |
@Serializable
data class Test(val nullableClass: Inner?, val nullableMap: Map<String, String>?)
@Serializable
data class Inner(val test: Int)
val test = Test(nullableClass = null, nullableMap = null)
Cbor.encodeToByteArray(Test.serializer(), test)
// Hex output: bf6d6e756c6c61626c65436c617373a06b6e756c6c61626c654d6170f6ff The hex output
Expected output would be this:
|
+1 on this I am working on a project that involves ISO 18013-5 (mDL) That type is used in cryptographic operations - so the values must match (each party creates the SessionTranscript independently) For sake of clarity, a simplified version of the type could be:
Describe the solution you'd like Using cbor (with useDefiniteLengthEncoding = true) like so:
Should encode to:
Maybe with some other CborBuilder option and/or annotation? As mentioned: Rough changes - but that would be breaking to existing consumers expecting this as the default behavior Maybe a "CborBuilder" opt-in for this behavior change? |
It does indeed sound like a bug and fixing would be a breaking change. One more thing regarding mDL: |
I appreciate the example @JesusMcCloud, as well as the heads up about EUDIW/Obor. Do you think it makes sense to that CborBuilder option to opt-in to this breaking change? |
That is for @sandwwraith to decide. @Jacob-Amazon has me convinced that the original behaviour is incorrect and should be resolved. How to handle such a breaking change wrt. the existing ecosystem using this cbor implementation is a different cup of tea I don't feel qualified/experienced enough to comment on. |
Now that I've seen this issue, I'm also convinced that a null object should be encoded as |
Just to clarify publicly: The EU consortium did not botch it. The ISO mDL spec itself loosened up some encoding rules compared to vanilla CBOR/COSE. So that consortium is to blame. |
I think we cannot change behavior as-is, indeed. You can send a PR that would incorporate the correct behavior under the flag. |
While I do understand the compatibility argument, isn't CBOR still experimental? I'm not advocating for a radical breaking change, but rather a sensible strategy to make the default behaviour gradually the default:
Probably too naive and never going to work as easily, but keeping known-wrong behaviour for to maintain compatibility with a state that is officially experimental smells funky. Alternatively: Deprecate this here CBOR format and replace it by something entirely new, heavily based on the much more flexible Obor. I think a discussion (both internally in the serialization team and with users) is warranted, because in the end the current behaviour remains wrong. |
I've made a PR for the first draft of this with the flag discussed. Hopefully it is a reasonable jumping off point. |
Traced to this line:
kotlinx.serialization/formats/cbor/commonMain/src/kotlinx/serialization/cbor/internal/Encoder.kt
Line 106 in d4d066d
I consider this a bug. Null objects should be encoded as the simple type
null
, no matter whether they are class types or other types.In our use case, this is causing issues after deserialization, since the empty map is deserialized into a default instance of the type, rather than
null
.Please consider removing this line and always encoding as
null
.The text was updated successfully, but these errors were encountered: