-
Notifications
You must be signed in to change notification settings - Fork 635
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
CBOR serializer encodes null class instance as empty map instead of null #2848
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: