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
sequence deserialization doesn't check the length after deserialize_seq and deserialize_map, leading to a situation where data types may incorrectly succeed at deserializing because they read elements that were incorrectly left unconsumed by the sequence visitor
Details
MessagePack arrays & maps are a tagged length prefix, followed by simply by that many objects, serialized in order.
This represents the following structure, except that the first byte claims that what follows is a map containing 3 entries, when there are only 2 available:
{
"a": ["a", "c", "d"],
"b": "c"
}
However, suppose that we attempt to deserialize this into this struct:
This will incorrectly successfully serialize. When the [String; 1] deserializes, it will begin deserializing a sequence, and consume the "a". However, it will then stop deserializing and report a success, even though the "c" and "d" haven't been consumed yet. However, because the Outer struct is expecting two more entries, it will parse the "c", "d" as c: "d", parse the trailing b: "c", then return with a success report.
This problem occurs with any type that deserializes a fixed number of elements (arrays, tuples, structs in sequence mode). It doesn't appear with structs in map mode, because those structs loop over all incoming keys with while let Some(key) = access.next_key_seed(seed)? {, which means that they will always parse N elements, even if N != num_fields.
The solution to this problem is to modify the SeqAccess and MapAccess structs to use a references to a usize:
Summary
sequence deserialization doesn't check the length after deserialize_seq and deserialize_map, leading to a situation where data types may incorrectly succeed at deserializing because they read elements that were incorrectly left unconsumed by the sequence visitor
Details
MessagePack arrays & maps are a tagged length prefix, followed by simply by that many objects, serialized in order.
Consider this (malformed) input:
This represents the following structure, except that the first byte claims that what follows is a map containing 3 entries, when there are only 2 available:
However, suppose that we attempt to deserialize this into this struct:
This will incorrectly successfully serialize. When the
[String; 1]
deserializes, it will begin deserializing a sequence, and consume the"a"
. However, it will then stop deserializing and report a success, even though the"c"
and"d"
haven't been consumed yet. However, because theOuter
struct is expecting two more entries, it will parse the"c", "d"
asc: "d"
, parse the trailingb: "c"
, then return with a success report.This problem occurs with any type that deserializes a fixed number of elements (arrays, tuples, structs in sequence mode). It doesn't appear with structs in map mode, because those structs loop over all incoming keys with
while let Some(key) = access.next_key_seed(seed)? {
, which means that they will always parseN
elements, even ifN != num_fields
.The solution to this problem is to modify the
SeqAccess
andMapAccess
structs to use a references to ausize
:Then, in the deserializer, pass a local mutable usize and check that it has counted down to 0 after the
visit_seq
orvisit_map
has completed.The text was updated successfully, but these errors were encountered: