serde_qs/de/
mod.rs

1//! Deserialization support for querystrings.
2
3//! ### An overview of the design of `QsDeserializer`
4//!
5//! This code is designed to handle non-ordered query parameters. For example,
6//! `struct { a: Vec<u8>, b: String }` might be serialized as either
7//! `a[0]=1&a[1]=2&b=Hello or a[1]=2&b=Hello&a[0]=1`.
8//!
9//! In order to cover the latter case, we have two options: scan through the
10//! string each time we need to find a particular key - worst case O(n^2 )
11//! running time; or pre-parse the list into a map structure, and then
12//! deserialize the map.
13//!
14//! We opt for the latter. But a TODO is implement the first case, which could
15//! potentially be more desirable, especially when the keys are known to be in
16//! order.
17//!
18//! The `parse` module handles this step of deserializing a querystring into the
19//! map structure. This uses `rust_url::percent_encoding` to handle
20//! first converting the string.
21//!
22//! From here, there are two main `Deserializer` objects: `QsDeserializer` and
23//! `LevelDeserializer`.
24//!
25//! The former is the top-level deserializer which is effectively only capable
26//! of deserializing map-like objects (i.e. those with (key, value) pairs).
27//! Hence, structs, maps, and enums are supported at this level.
28//!
29//! Each key is a `String`, and deserialized from a `String`. The values are
30//! `Level` elements. This is a recursive structure which can either be a "flat
31//! value", i.e. just a string, or a sequence or map of these elements. This can
32//! be thought of as similar to the `serde_json::Value` enum.
33//!
34//! Each `Level` can be deserialized through `LevelDeserializer`. This will
35//! recursively call back to the top level `QsDeserializer` for maps, or when
36//! `Level` is a flat value it will attempt to deserialize it to a primitive via
37//! `ParsableStringDeserializer`.
38
39mod parse;
40
41use crate::error::*;
42
43use serde::de;
44use serde::de::IntoDeserializer;
45
46use std::borrow::Cow;
47use std::collections::btree_map::{BTreeMap, Entry, IntoIter};
48
49/// To override the default serialization parameters, first construct a new
50/// Config.
51///
52/// The `strict` parameter controls whether the deserializer will tolerate
53/// encoded brackets as part of the key. For example, serializing the field
54/// `a = vec![12]` might give `a[0]=12`. In strict mode, the only string accepted
55/// will be this string, whereas in non-strict mode, this can also be deserialized
56/// from `a%5B0%5D=12`. Strict mode is more accurate for cases where it a field
57/// may contain square brackets.
58/// In non-strict mode, the deserializer will generally tolerate unexpected
59/// characters.
60///
61/// A `max_depth` of 0 implies no nesting: the result will be a flat map.
62/// This is mostly useful when the maximum nested depth is known beforehand,
63/// to prevent denial of service attacks by providing incredibly deeply nested
64/// inputs.
65///
66/// The default value for `max_depth` is 5, and the default mode is `strict=true`.
67///
68/// ```
69/// use serde_qs::Config;
70/// use std::collections::HashMap;
71///
72/// let config = Config::new(0, true);
73/// let map: HashMap<String, String> = config.deserialize_str("a[b][c]=1")
74///                                          .unwrap();
75/// assert_eq!(map.get("a[b][c]").unwrap(), "1");
76///
77/// let config = Config::new(10, true);
78/// let map: HashMap<String, HashMap<String, HashMap<String, String>>> =
79///             config.deserialize_str("a[b][c]=1").unwrap();
80/// assert_eq!(map.get("a").unwrap().get("b").unwrap().get("c").unwrap(), "1");
81/// ```
82///
83pub struct Config {
84    /// Specifies the maximum depth key that `serde_qs` will attempt to
85    /// deserialize. Default is 5.
86    max_depth: usize,
87    /// Strict deserializing mode will not tolerate encoded brackets.
88    strict: bool,
89}
90
91impl Default for Config {
92    fn default() -> Self {
93        Self::new(5, true)
94    }
95}
96
97impl Config {
98    /// Create a new `Config` with the specified `max_depth` and `strict` mode.
99    pub fn new(max_depth: usize, strict: bool) -> Self {
100        Self { max_depth, strict }
101    }
102
103    /// Get maximum depth parameter.
104    fn max_depth(&self) -> usize {
105        self.max_depth
106    }
107}
108
109impl Config {
110    /// Deserializes a querystring from a `&[u8]` using this `Config`.
111    pub fn deserialize_bytes<'de, T: de::Deserialize<'de>>(&self, input: &'de [u8]) -> Result<T> {
112        T::deserialize(QsDeserializer::with_config(self, input)?)
113    }
114
115    // pub fn deserialize_bytes_sloppy<T: de::DeserializeOwned>(&self, input: &[u8])
116    //     -> Result<T>
117    // {
118    //     let buf = String::from_utf8(input.to_vec())?;
119    //     let buf = buf.replace("%5B", "[").replace("%5D", "]").into_bytes();
120    //     let deser = QsDeserializer::with_config(self, &buf)?;
121    //     T::deserialize(deser)
122    // }
123
124    /// Deserializes a querystring from a `&str` using this `Config`.
125    pub fn deserialize_str<'de, T: de::Deserialize<'de>>(&self, input: &'de str) -> Result<T> {
126        self.deserialize_bytes(input.as_bytes())
127    }
128}
129
130/// Deserializes a querystring from a `&[u8]`.
131///
132/// ```
133/// # #[macro_use]
134/// # extern crate serde_derive;
135/// # extern crate serde_qs;
136/// #[derive(Debug, Deserialize, PartialEq, Serialize)]
137/// struct Query {
138///     name: String,
139///     age: u8,
140///     occupation: String,
141/// }
142///
143/// # fn main(){
144/// let q =  Query {
145///     name: "Alice".to_owned(),
146///     age: 24,
147///     occupation: "Student".to_owned(),
148/// };
149///
150/// assert_eq!(
151///     serde_qs::from_bytes::<Query>(
152///         "name=Alice&age=24&occupation=Student".as_bytes()
153///     ).unwrap(), q);
154/// # }
155/// ```
156pub fn from_bytes<'de, T: de::Deserialize<'de>>(input: &'de [u8]) -> Result<T> {
157    Config::default().deserialize_bytes(input)
158}
159
160/// Deserializes a querystring from a `&str`.
161///
162/// ```
163/// # #[macro_use]
164/// # extern crate serde_derive;
165/// # extern crate serde_qs;
166/// #[derive(Debug, Deserialize, PartialEq, Serialize)]
167/// struct Query {
168///     name: String,
169///     age: u8,
170///     occupation: String,
171/// }
172///
173/// # fn main(){
174/// let q =  Query {
175///     name: "Alice".to_owned(),
176///     age: 24,
177///     occupation: "Student".to_owned(),
178/// };
179///
180/// assert_eq!(
181///     serde_qs::from_str::<Query>("name=Alice&age=24&occupation=Student").unwrap(),
182///     q);
183/// # }
184/// ```
185pub fn from_str<'de, T: de::Deserialize<'de>>(input: &'de str) -> Result<T> {
186    from_bytes(input.as_bytes())
187}
188
189/// A deserializer for the querystring format.
190///
191/// Supported top-level outputs are structs and maps.
192pub(crate) struct QsDeserializer<'a> {
193    iter: IntoIter<Cow<'a, str>, Level<'a>>,
194    value: Option<Level<'a>>,
195}
196
197#[derive(Debug)]
198enum Level<'a> {
199    Nested(BTreeMap<Cow<'a, str>, Level<'a>>),
200    OrderedSeq(BTreeMap<usize, Level<'a>>),
201    Sequence(Vec<Level<'a>>),
202    Flat(Cow<'a, str>),
203    Invalid(String),
204    Uninitialised,
205}
206
207impl<'a> QsDeserializer<'a> {
208    fn with_map(map: BTreeMap<Cow<'a, str>, Level<'a>>) -> Self {
209        QsDeserializer {
210            iter: map.into_iter(),
211            value: None,
212        }
213    }
214
215    /// Returns a new `QsDeserializer<'a>`.
216    fn with_config(config: &Config, input: &'a [u8]) -> Result<Self> {
217        parse::Parser::new(input, config.max_depth(), config.strict).as_deserializer()
218    }
219}
220
221impl<'de> de::Deserializer<'de> for QsDeserializer<'de> {
222    type Error = Error;
223
224    fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value>
225    where
226        V: de::Visitor<'de>,
227    {
228        if self.iter.next().is_none() {
229            return visitor.visit_unit();
230        }
231
232        Err(Error::top_level("primitive"))
233    }
234
235    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
236    where
237        V: de::Visitor<'de>,
238    {
239        visitor.visit_map(self)
240    }
241
242    fn deserialize_struct<V>(
243        self,
244        _name: &'static str,
245        _fields: &'static [&'static str],
246        visitor: V,
247    ) -> Result<V::Value>
248    where
249        V: de::Visitor<'de>,
250    {
251        self.deserialize_map(visitor)
252    }
253
254    /// Throws an error.
255    ///
256    /// Sequences are not supported at the top level.
257    fn deserialize_seq<V>(self, _visitor: V) -> Result<V::Value>
258    where
259        V: de::Visitor<'de>,
260    {
261        Err(Error::top_level("sequence"))
262    }
263
264    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
265    where
266        V: de::Visitor<'de>,
267    {
268        self.deserialize_map(visitor)
269    }
270
271    /// Throws an error.
272    ///
273    /// Tuples are not supported at the top level.
274    fn deserialize_tuple<V>(self, _len: usize, _visitor: V) -> Result<V::Value>
275    where
276        V: de::Visitor<'de>,
277    {
278        Err(Error::top_level("tuple"))
279    }
280
281    /// Throws an error.
282    ///
283    /// TupleStructs are not supported at the top level.
284    fn deserialize_tuple_struct<V>(
285        self,
286        _name: &'static str,
287        _len: usize,
288        _visitor: V,
289    ) -> Result<V::Value>
290    where
291        V: de::Visitor<'de>,
292    {
293        Err(Error::top_level("tuple struct"))
294    }
295
296    fn deserialize_enum<V>(
297        self,
298        _name: &'static str,
299        _variants: &'static [&'static str],
300        visitor: V,
301    ) -> Result<V::Value>
302    where
303        V: de::Visitor<'de>,
304    {
305        visitor.visit_enum(self)
306    }
307
308    forward_to_deserialize_any! {
309        bool
310        u8
311        u16
312        u32
313        u64
314        i8
315        i16
316        i32
317        i64
318        f32
319        f64
320        char
321        str
322        string
323        unit
324        option
325        bytes
326        byte_buf
327        unit_struct
328        identifier
329        ignored_any
330    }
331}
332
333impl<'de> de::MapAccess<'de> for QsDeserializer<'de> {
334    type Error = Error;
335
336    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
337    where
338        K: de::DeserializeSeed<'de>,
339    {
340        if let Some((key, value)) = self.iter.next() {
341            self.value = Some(value);
342            let has_bracket = key.contains('[');
343            seed.deserialize(ParsableStringDeserializer(key))
344                .map(Some)
345                .map_err(|e| {
346                    if has_bracket {
347                        de::Error::custom(
348                            format!("{}\nInvalid field contains an encoded bracket -- did you mean to use non-strict mode?\n  https://docs.rs/serde_qs/latest/serde_qs/#strict-vs-non-strict-modes", e,)
349                        )
350                    } else {
351                        e
352                    }
353                })
354        } else {
355            Ok(None)
356        }
357    }
358
359    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
360    where
361        V: de::DeserializeSeed<'de>,
362    {
363        if let Some(v) = self.value.take() {
364            seed.deserialize(LevelDeserializer(v))
365        } else {
366            Err(de::Error::custom(
367                "Somehow the map was empty after a non-empty key was returned",
368            ))
369        }
370    }
371}
372
373impl<'de> de::EnumAccess<'de> for QsDeserializer<'de> {
374    type Error = Error;
375    type Variant = Self;
376
377    fn variant_seed<V>(mut self, seed: V) -> Result<(V::Value, Self::Variant)>
378    where
379        V: de::DeserializeSeed<'de>,
380    {
381        if let Some((key, value)) = self.iter.next() {
382            self.value = Some(value);
383            Ok((seed.deserialize(ParsableStringDeserializer(key))?, self))
384        } else {
385            Err(de::Error::custom("No more values"))
386        }
387    }
388}
389
390impl<'de> de::VariantAccess<'de> for QsDeserializer<'de> {
391    type Error = Error;
392    fn unit_variant(self) -> Result<()> {
393        Ok(())
394    }
395
396    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
397    where
398        T: de::DeserializeSeed<'de>,
399    {
400        if let Some(value) = self.value {
401            seed.deserialize(LevelDeserializer(value))
402        } else {
403            Err(de::Error::custom("no value to deserialize"))
404        }
405    }
406    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
407    where
408        V: de::Visitor<'de>,
409    {
410        if let Some(value) = self.value {
411            de::Deserializer::deserialize_seq(LevelDeserializer(value), visitor)
412        } else {
413            Err(de::Error::custom("no value to deserialize"))
414        }
415    }
416    fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
417    where
418        V: de::Visitor<'de>,
419    {
420        if let Some(value) = self.value {
421            de::Deserializer::deserialize_map(LevelDeserializer(value), visitor)
422        } else {
423            Err(de::Error::custom("no value to deserialize"))
424        }
425    }
426}
427
428impl<'de> de::EnumAccess<'de> for LevelDeserializer<'de> {
429    type Error = Error;
430    type Variant = Self;
431
432    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
433    where
434        V: de::DeserializeSeed<'de>,
435    {
436        match self.0 {
437            Level::Flat(x) => Ok((
438                seed.deserialize(ParsableStringDeserializer(x))?,
439                LevelDeserializer(Level::Invalid(
440                    "this value can only \
441                     deserialize to a \
442                     UnitVariant"
443                        .to_string(),
444                )),
445            )),
446            _ => Err(de::Error::custom(
447                "this value can only deserialize to a \
448                 UnitVariant",
449            )),
450        }
451    }
452}
453
454impl<'de> de::VariantAccess<'de> for LevelDeserializer<'de> {
455    type Error = Error;
456    fn unit_variant(self) -> Result<()> {
457        Ok(())
458    }
459
460    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
461    where
462        T: de::DeserializeSeed<'de>,
463    {
464        seed.deserialize(self)
465    }
466    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
467    where
468        V: de::Visitor<'de>,
469    {
470        de::Deserializer::deserialize_seq(self, visitor)
471    }
472    fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
473    where
474        V: de::Visitor<'de>,
475    {
476        de::Deserializer::deserialize_map(self, visitor)
477    }
478}
479
480struct LevelSeq<'a, I: Iterator<Item = Level<'a>>>(I);
481
482impl<'de, I: Iterator<Item = Level<'de>>> de::SeqAccess<'de> for LevelSeq<'de, I> {
483    type Error = Error;
484    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
485    where
486        T: de::DeserializeSeed<'de>,
487    {
488        if let Some(v) = self.0.next() {
489            seed.deserialize(LevelDeserializer(v)).map(Some)
490        } else {
491            Ok(None)
492        }
493    }
494}
495
496struct LevelDeserializer<'a>(Level<'a>);
497
498macro_rules! deserialize_primitive {
499    ($ty:ident, $method:ident, $visit_method:ident) => {
500        fn $method<V>(self, visitor: V) -> Result<V::Value>
501        where
502            V: de::Visitor<'de>,
503        {
504            match self.0 {
505                Level::Nested(_) => Err(de::Error::custom(format!(
506                    "Expected: {:?}, got a Map",
507                    stringify!($ty)
508                ))),
509                Level::OrderedSeq(_) => Err(de::Error::custom(format!(
510                    "Expected: {:?}, got an OrderedSequence",
511                    stringify!($ty)
512                ))),
513                Level::Sequence(_) => Err(de::Error::custom(format!(
514                    "Expected: {:?}, got a Sequence",
515                    stringify!($ty)
516                ))),
517                Level::Flat(x) => ParsableStringDeserializer(x).$method(visitor),
518                Level::Invalid(e) => Err(de::Error::custom(e)),
519                Level::Uninitialised => Err(de::Error::custom(
520                    "attempted to deserialize unitialised value",
521                )),
522            }
523        }
524    };
525}
526
527impl<'a> LevelDeserializer<'a> {
528    fn into_deserializer(self) -> Result<QsDeserializer<'a>> {
529        match self.0 {
530            Level::Nested(map) => Ok(QsDeserializer::with_map(map)),
531            Level::OrderedSeq(map) => Ok(QsDeserializer::with_map(
532                map.into_iter()
533                    .map(|(k, v)| (Cow::Owned(k.to_string()), v))
534                    .collect(),
535            )),
536            Level::Invalid(e) => Err(de::Error::custom(e)),
537            l => Err(de::Error::custom(format!(
538                "could not convert {:?} to \
539                 QsDeserializer<'a>",
540                l
541            ))),
542        }
543    }
544}
545
546impl<'de> de::Deserializer<'de> for LevelDeserializer<'de> {
547    type Error = Error;
548
549    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
550    where
551        V: de::Visitor<'de>,
552    {
553        match self.0 {
554            Level::Nested(_) => self.into_deserializer()?.deserialize_map(visitor),
555            Level::OrderedSeq(map) => visitor.visit_seq(LevelSeq(map.into_values())),
556            Level::Sequence(seq) => visitor.visit_seq(LevelSeq(seq.into_iter())),
557            Level::Flat(x) => match x {
558                Cow::Owned(s) => visitor.visit_string(s),
559                Cow::Borrowed(s) => visitor.visit_borrowed_str(s),
560            },
561            Level::Invalid(e) => Err(de::Error::custom(e)),
562            Level::Uninitialised => Err(de::Error::custom(
563                "attempted to deserialize unitialised \
564                 value",
565            )),
566        }
567    }
568
569    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
570    where
571        V: de::Visitor<'de>,
572    {
573        match self.0 {
574            Level::Flat(ref x) if x == "" => visitor.visit_none(),
575            _ => visitor.visit_some(self),
576        }
577    }
578
579    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
580    where
581        V: de::Visitor<'de>,
582    {
583        match self.0 {
584            Level::Flat(ref x) if x == "" => visitor.visit_unit(),
585            _ => Err(de::Error::custom("expected unit".to_owned())),
586        }
587    }
588
589    fn deserialize_enum<V>(
590        self,
591        name: &'static str,
592        variants: &'static [&'static str],
593        visitor: V,
594    ) -> Result<V::Value>
595    where
596        V: de::Visitor<'de>,
597    {
598        match self.0 {
599            Level::Nested(map) => {
600                QsDeserializer::with_map(map).deserialize_enum(name, variants, visitor)
601            }
602            Level::Flat(_) => visitor.visit_enum(self),
603            x => Err(de::Error::custom(format!(
604                "{:?} does not appear to be \
605                 an enum",
606                x
607            ))),
608        }
609    }
610
611    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
612    where
613        V: de::Visitor<'de>,
614    {
615        match self.0 {
616            Level::Nested(_) => self.into_deserializer()?.deserialize_map(visitor),
617            Level::OrderedSeq(map) => visitor.visit_seq(LevelSeq(map.into_values())),
618            Level::Sequence(seq) => visitor.visit_seq(LevelSeq(seq.into_iter())),
619            Level::Flat(_) => {
620                // For a newtype_struct, attempt to deserialize a flat value as a
621                // single element sequence.
622                visitor.visit_seq(LevelSeq(vec![self.0].into_iter()))
623            }
624            Level::Invalid(e) => Err(de::Error::custom(e)),
625            Level::Uninitialised => Err(de::Error::custom(
626                "attempted to deserialize unitialised \
627                 value",
628            )),
629        }
630    }
631
632    /// given the hint that this is a map, will first
633    /// attempt to deserialize ordered sequences into a map
634    /// otherwise, follows the any code path
635    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
636    where
637        V: de::Visitor<'de>,
638    {
639        match self.0 {
640            Level::OrderedSeq(_) => self.into_deserializer()?.deserialize_map(visitor),
641            _ => self.deserialize_any(visitor),
642        }
643    }
644
645    deserialize_primitive!(bool, deserialize_bool, visit_bool);
646    deserialize_primitive!(i8, deserialize_i8, visit_i8);
647    deserialize_primitive!(i16, deserialize_i16, visit_i16);
648    deserialize_primitive!(i32, deserialize_i32, visit_i32);
649    deserialize_primitive!(i64, deserialize_i64, visit_i64);
650    deserialize_primitive!(u8, deserialize_u8, visit_u8);
651    deserialize_primitive!(u16, deserialize_u16, visit_u16);
652    deserialize_primitive!(u32, deserialize_u32, visit_u32);
653    deserialize_primitive!(u64, deserialize_u64, visit_u64);
654    deserialize_primitive!(f32, deserialize_f32, visit_f32);
655    deserialize_primitive!(f64, deserialize_f64, visit_f64);
656
657    forward_to_deserialize_any! {
658        char
659        str
660        string
661        bytes
662        byte_buf
663        unit_struct
664        // newtype_struct
665        tuple_struct
666        struct
667        identifier
668        tuple
669        ignored_any
670        seq
671        // map
672    }
673}
674
675macro_rules! forward_parsable_to_deserialize_any {
676    ($($ty:ident => $meth:ident,)*) => {
677        $(
678            fn $meth<V>(self, visitor: V) -> Result<V::Value> where V: de::Visitor<'de> {
679                match self.0.parse::<$ty>() {
680                    Ok(val) => val.into_deserializer().$meth(visitor),
681                    Err(e) => Err(de::Error::custom(e))
682                }
683            }
684        )*
685    }
686}
687
688struct ParsableStringDeserializer<'a>(Cow<'a, str>);
689
690impl<'de> de::Deserializer<'de> for ParsableStringDeserializer<'de> {
691    type Error = Error;
692
693    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
694    where
695        V: de::Visitor<'de>,
696    {
697        self.0.into_deserializer().deserialize_any(visitor)
698    }
699
700    fn deserialize_enum<V>(
701        self,
702        _: &'static str,
703        _: &'static [&'static str],
704        visitor: V,
705    ) -> Result<V::Value>
706    where
707        V: de::Visitor<'de>,
708    {
709        visitor.visit_enum(LevelDeserializer(Level::Flat(self.0)))
710    }
711
712    forward_to_deserialize_any! {
713        map
714        struct
715        seq
716        option
717        char
718        str
719        string
720        unit
721        bytes
722        byte_buf
723        unit_struct
724        newtype_struct
725        tuple_struct
726        identifier
727        tuple
728        ignored_any
729    }
730
731    forward_parsable_to_deserialize_any! {
732        bool => deserialize_bool,
733        u8 => deserialize_u8,
734        u16 => deserialize_u16,
735        u32 => deserialize_u32,
736        u64 => deserialize_u64,
737        i8 => deserialize_i8,
738        i16 => deserialize_i16,
739        i32 => deserialize_i32,
740        i64 => deserialize_i64,
741        f32 => deserialize_f32,
742        f64 => deserialize_f64,
743    }
744}