values_deserialization.rs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. // Copyright 2022 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. use crate::values::{DictValueRef, ListValueRef, ValueSlotRef};
  5. use serde::de::{DeserializeSeed, Deserializer, Error, MapAccess, SeqAccess, Visitor};
  6. use std::convert::TryFrom;
  7. use std::fmt;
  8. /// Struct to check we're not recursing too deeply.
  9. #[derive(Clone)]
  10. struct RecursionDepthCheck(usize);
  11. impl RecursionDepthCheck {
  12. /// Recurse a level and return an error if we've recursed too far.
  13. fn recurse<E: Error>(&self) -> Result<RecursionDepthCheck, E> {
  14. match self.0.checked_sub(1) {
  15. Some(recursion_limit) => Ok(RecursionDepthCheck(recursion_limit)),
  16. None => Err(Error::custom("recursion limit exceeded")),
  17. }
  18. }
  19. }
  20. /// What type of `base::Value` container we're deserializing into.
  21. enum DeserializationTarget<'elem, 'container> {
  22. /// Deserialize into a brand new root `base::Value`.
  23. NewValue { slot: ValueSlotRef<'container> },
  24. /// Deserialize by appending to a list.
  25. List { list: &'elem mut ListValueRef<'container> },
  26. /// Deserialize by setting a dictionary key.
  27. Dict { dict: &'elem mut DictValueRef<'container>, key: String },
  28. }
  29. /// serde deserializer for for `base::Value`.
  30. ///
  31. /// serde is the "standard" framework for serializing and deserializing
  32. /// data formats in Rust. https://serde.rs/
  33. ///
  34. /// This implements both the Visitor and Deserialize roles described
  35. /// here: https://serde.rs/impl-deserialize.html
  36. ///
  37. /// One note, though. Normally serde instantiates a new object. The design
  38. /// of `base::Value` is that each sub-value (e.g. a list like this)
  39. /// needs to be deserialized into the parent value, which is pre-existing.
  40. /// To achieve this we use a feature of serde called 'stateful deserialization'
  41. /// (see https://docs.serde.rs/serde/de/trait.DeserializeSeed.html)
  42. ///
  43. /// This struct stores that state.
  44. ///
  45. /// Handily, this also enables us to store the desired recursion limit.
  46. ///
  47. /// We use runtime dispatch (matching on an enum) to deserialize into a
  48. /// dictionary, list, etc. This may be slower than having three different
  49. /// `Visitor` implementations, where everything would be monomorphized
  50. /// and would probably disappear with inlining, but for now this is much
  51. /// less code.
  52. pub struct ValueVisitor<'elem, 'container> {
  53. container: DeserializationTarget<'elem, 'container>,
  54. recursion_depth_check: RecursionDepthCheck,
  55. }
  56. impl<'elem, 'container> ValueVisitor<'elem, 'container> {
  57. /// Constructor - pass in an existing slot that can store a new
  58. /// `base::Value`, then this visitor can be passed to serde deserialization
  59. /// libraries to populate it with a tree of contents.
  60. /// Any existing `base::Value` in the slot will be replaced.
  61. pub fn new(slot: ValueSlotRef<'container>, mut max_depth: usize) -> Self {
  62. max_depth += 1; // we will increment this counter when deserializing
  63. // the initial `base::Value`. To match C++ behavior, we should
  64. // only start counting for subsequent layers, hence decrement
  65. // now.
  66. Self {
  67. container: DeserializationTarget::NewValue { slot },
  68. recursion_depth_check: RecursionDepthCheck(max_depth),
  69. }
  70. }
  71. }
  72. impl<'de, 'elem, 'container> Visitor<'de> for ValueVisitor<'elem, 'container> {
  73. // Because we are deserializing into a pre-existing object.
  74. type Value = ();
  75. fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
  76. formatter.write_str("any valid JSON")
  77. }
  78. fn visit_i32<E: serde::de::Error>(self, value: i32) -> Result<Self::Value, E> {
  79. match self.container {
  80. DeserializationTarget::NewValue { mut slot } => slot.construct_integer(value),
  81. DeserializationTarget::List { list } => list.append_integer(value),
  82. DeserializationTarget::Dict { dict, key } => dict.set_integer_key(&key, value),
  83. };
  84. Ok(())
  85. }
  86. fn visit_i8<E: serde::de::Error>(self, value: i8) -> Result<Self::Value, E> {
  87. self.visit_i32(value as i32)
  88. }
  89. fn visit_bool<E: serde::de::Error>(self, value: bool) -> Result<Self::Value, E> {
  90. match self.container {
  91. DeserializationTarget::NewValue { mut slot } => slot.construct_bool(value),
  92. DeserializationTarget::List { list } => list.append_bool(value),
  93. DeserializationTarget::Dict { dict, key } => dict.set_bool_key(&key, value),
  94. };
  95. Ok(())
  96. }
  97. fn visit_i64<E: serde::de::Error>(self, value: i64) -> Result<Self::Value, E> {
  98. // Here we match the behavior of the Chromium C++ JSON parser,
  99. // which will attempt to create an integer base::Value but will
  100. // overflow into a double if needs be.
  101. // (See JSONParser::ConsumeNumber in json_parser.cc for equivalent,
  102. // and json_reader_unittest.cc LargerIntIsLossy for a related test).
  103. match i32::try_from(value) {
  104. Ok(value) => self.visit_i32(value),
  105. Err(_) => self.visit_f64(value as f64),
  106. }
  107. }
  108. fn visit_u64<E: serde::de::Error>(self, value: u64) -> Result<Self::Value, E> {
  109. // See visit_i64 comment.
  110. match i32::try_from(value) {
  111. Ok(value) => self.visit_i32(value),
  112. Err(_) => self.visit_f64(value as f64),
  113. }
  114. }
  115. fn visit_f64<E: serde::de::Error>(self, value: f64) -> Result<Self::Value, E> {
  116. match self.container {
  117. DeserializationTarget::NewValue { mut slot } => slot.construct_double(value),
  118. DeserializationTarget::List { list } => list.append_double(value),
  119. DeserializationTarget::Dict { dict, key } => dict.set_double_key(&key, value),
  120. };
  121. Ok(())
  122. }
  123. fn visit_str<E: serde::de::Error>(self, value: &str) -> Result<Self::Value, E> {
  124. match self.container {
  125. DeserializationTarget::NewValue { mut slot } => slot.construct_string(value),
  126. DeserializationTarget::List { list } => list.append_string(value),
  127. DeserializationTarget::Dict { dict, key } => dict.set_string_key(&key, value),
  128. };
  129. Ok(())
  130. }
  131. fn visit_borrowed_str<E: serde::de::Error>(self, value: &'de str) -> Result<Self::Value, E> {
  132. match self.container {
  133. DeserializationTarget::NewValue { mut slot } => slot.construct_string(value),
  134. DeserializationTarget::List { list } => list.append_string(value),
  135. DeserializationTarget::Dict { dict, key } => dict.set_string_key(&key, value),
  136. };
  137. Ok(())
  138. }
  139. fn visit_string<E: serde::de::Error>(self, value: String) -> Result<Self::Value, E> {
  140. self.visit_str(&value)
  141. }
  142. fn visit_none<E: serde::de::Error>(self) -> Result<Self::Value, E> {
  143. match self.container {
  144. DeserializationTarget::NewValue { mut slot } => slot.construct_none(),
  145. DeserializationTarget::List { list } => list.append_none(),
  146. DeserializationTarget::Dict { dict, key } => dict.set_none_key(&key),
  147. };
  148. Ok(())
  149. }
  150. fn visit_unit<E: serde::de::Error>(self) -> Result<Self::Value, E> {
  151. self.visit_none()
  152. }
  153. fn visit_map<M>(mut self, mut access: M) -> Result<Self::Value, M::Error>
  154. where
  155. M: MapAccess<'de>,
  156. {
  157. let mut value = match self.container {
  158. DeserializationTarget::NewValue { ref mut slot } => slot.construct_dict(),
  159. DeserializationTarget::List { list } => list.append_dict(),
  160. DeserializationTarget::Dict { dict, key } => dict.set_dict_key(&key),
  161. };
  162. // If it were exposed by values.h, we could use access.size_hint()
  163. // to give a clue to the C++ about the size of the desired map.
  164. while let Some(key) = access.next_key::<String>()? {
  165. access.next_value_seed(ValueVisitor {
  166. container: DeserializationTarget::Dict { dict: &mut value, key },
  167. recursion_depth_check: self.recursion_depth_check.recurse()?,
  168. })?;
  169. }
  170. Ok(())
  171. }
  172. fn visit_seq<S>(mut self, mut access: S) -> Result<Self::Value, S::Error>
  173. where
  174. S: SeqAccess<'de>,
  175. {
  176. let mut value = match self.container {
  177. DeserializationTarget::NewValue { ref mut slot } => slot.construct_list(),
  178. DeserializationTarget::List { list } => list.append_list(),
  179. DeserializationTarget::Dict { dict, key } => dict.set_list_key(&key),
  180. };
  181. if let Some(size_hint) = access.size_hint() {
  182. value.reserve_size(size_hint);
  183. }
  184. while let Some(_) = access.next_element_seed(ValueVisitor {
  185. container: DeserializationTarget::List { list: &mut value },
  186. recursion_depth_check: self.recursion_depth_check.recurse()?,
  187. })? {}
  188. Ok(())
  189. }
  190. }
  191. impl<'de, 'elem, 'container> DeserializeSeed<'de> for ValueVisitor<'elem, 'container> {
  192. // Because we are deserializing into a pre-existing object.
  193. type Value = ();
  194. fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
  195. where
  196. D: Deserializer<'de>,
  197. {
  198. deserializer.deserialize_any(self)
  199. }
  200. }