Skip to content

Commit

Permalink
Don't ignore additional entries in UntypedReflectDeserializerVisitor (
Browse files Browse the repository at this point in the history
bevyengine#7112)

# Objective

Currently when `UntypedReflectDeserializerVisitor` deserializes a
`Box<dyn Reflect>` it only considers the first entry of the map,
silently ignoring any additional entries. For example the following RON
data:

```json
{
    "f32": 1.23,
    "u32": 1,
}
```

is successfully deserialized as a `f32`, completly ignoring the `"u32":
1` part.

## Solution

`UntypedReflectDeserializerVisitor` was changed to check if any other
key could be deserialized, and in that case returns an error.

---

## Changelog

`UntypedReflectDeserializer` now errors on malformed inputs instead of
silently disgarding additional data.

## Migration Guide

If you were deserializing `Box<dyn Reflect>` values with multiple
entries (i.e. entries other than `"type": { /* fields */ }`) you should
remove them or deserialization will fail.
  • Loading branch information
SkiFire13 committed Jun 26, 2023
1 parent 8fa94a0 commit 0f4d16a
Showing 1 changed file with 9 additions and 2 deletions.
11 changes: 9 additions & 2 deletions crates/bevy_reflect/src/serde/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use crate::{
};
use erased_serde::Deserializer;
use serde::de::{
self, DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor,
self, DeserializeSeed, EnumAccess, Error, IgnoredAny, MapAccess, SeqAccess, VariantAccess,
Visitor,
};
use serde::Deserialize;
use std::any::TypeId;
Expand Down Expand Up @@ -322,11 +323,17 @@ impl<'a, 'de> Visitor<'de> for UntypedReflectDeserializerVisitor<'a> {
{
let registration = map
.next_key_seed(TypeRegistrationDeserializer::new(self.registry))?
.ok_or_else(|| Error::invalid_length(0, &"at least one entry"))?;
.ok_or_else(|| Error::invalid_length(0, &"a single entry"))?;

let value = map.next_value_seed(TypedReflectDeserializer {
registration,
registry: self.registry,
})?;

if map.next_key::<IgnoredAny>()?.is_some() {
return Err(Error::invalid_length(2, &"a single entry"));
}

Ok(value)
}
}
Expand Down

0 comments on commit 0f4d16a

Please sign in to comment.