From 0f4d16aa3ce9a7937d253313b6f821c6eeb09c10 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Mon, 26 Jun 2023 21:32:27 +0200 Subject: [PATCH] Don't ignore additional entries in `UntypedReflectDeserializerVisitor` (#7112) # Objective Currently when `UntypedReflectDeserializerVisitor` deserializes a `Box` 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` values with multiple entries (i.e. entries other than `"type": { /* fields */ }`) you should remove them or deserialization will fail. --- crates/bevy_reflect/src/serde/de.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/crates/bevy_reflect/src/serde/de.rs b/crates/bevy_reflect/src/serde/de.rs index de7c474381..9fe3cd0288 100644 --- a/crates/bevy_reflect/src/serde/de.rs +++ b/crates/bevy_reflect/src/serde/de.rs @@ -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; @@ -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::()?.is_some() { + return Err(Error::invalid_length(2, &"a single entry")); + } + Ok(value) } }