You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Quick context:
In msgpack-rust, enums are currently serialized as maps with a single key / value, where the key = an integer / string, and the value is any associated data. I'm changing it so that if enums are unit variants, then they aren't serialized as maps.
Explanation of the code:
The code above checks if there is a map, if there is, it will deserialize the enum using VariantAccess, which will handle any associated data, otherwise, we deserialize the enum as a unit variant using UnitVariantAccess (I should be doing a check here to see whether the "marker" is a valid integer / string). The problem is that take_or_read_marker consumes the token, (unlike in serde_json, where parse_whitespace does not consume the token), in the UnitVariantAccess case, this causes variant_seed to try to deserialize what is after the enum into an enum variant, which causes a bug.
We have the enum: enum Foo { A, B }.
The MessagePack data buffer is [0, 1]. visit_enum reads the 0 "marker" and calls visitor.visit_enum(UnitVariantAccess::new(self)), but the reader is now right before the 1, it then calls UnitVariantAccess::variant_seed, which will end up deserializing the 1 into variant B and leaving the reader at the end of the buffer. When in reality, we wanted to deserialize an A and leave the reader after the 0 but before the 1.
Was wondering if you had any thoughts on what to do.
Hope this makes sense!
The text was updated successfully, but these errors were encountered:
Leaving this open -- b/c not sure if this is the right way to do things. I understand this question is pretty vague though -- so feel free to close whenever.
I've been working on fixing the enum implementation in msgpack-rust: 3Hren/msgpack-rust#225.
I was looking at the implementation of enum deserialization here:
json/src/de.rs
Line 1837 in df1fb71
and tried to copy it for msgpack-rust.
My attempt is here:
https://github.com/vedantroy/msgpack-rust/blob/2da1609d9d66aee94e80b3640d5a3c0d93a6a8a7/rmp-serde/src/decode.rs#L639
Quick context:
In msgpack-rust, enums are currently serialized as maps with a single key / value, where the key = an integer / string, and the value is any associated data. I'm changing it so that if enums are unit variants, then they aren't serialized as maps.
Explanation of the code:
The code above checks if there is a map, if there is, it will deserialize the enum using
VariantAccess
, which will handle any associated data, otherwise, we deserialize the enum as a unit variant usingUnitVariantAccess
(I should be doing a check here to see whether the "marker" is a valid integer / string). The problem is thattake_or_read_marker
consumes the token, (unlike in serde_json, whereparse_whitespace
does not consume the token), in theUnitVariantAccess
case, this causesvariant_seed
to try to deserialize what is after the enum into an enum variant, which causes a bug.https://github.com/vedantroy/msgpack-rust/blob/2da1609d9d66aee94e80b3640d5a3c0d93a6a8a7/rmp-serde/src/decode.rs#L861
An example:
We have the enum:
enum Foo { A, B }
.The MessagePack data buffer is
[0, 1]
.visit_enum
reads the0
"marker" and callsvisitor.visit_enum(UnitVariantAccess::new(self))
, but the reader is now right before the1
, it then callsUnitVariantAccess::variant_seed
, which will end up deserializing the1
into variantB
and leaving the reader at the end of the buffer. When in reality, we wanted to deserialize anA
and leave the reader after the0
but before the1
.Was wondering if you had any thoughts on what to do.
Hope this makes sense!
The text was updated successfully, but these errors were encountered: