Skip to main content

zvariant/dbus/
de.rs

1use serde::de::{self, DeserializeSeed, EnumAccess, MapAccess, SeqAccess, Visitor};
2
3use std::{marker::PhantomData, str};
4
5#[cfg(unix)]
6use std::os::fd::AsFd;
7
8use crate::{
9    Basic, Error, ObjectPath, Result, Signature,
10    de::{DeserializerCommon, ValueParseStage},
11    serialized::{Context, Format},
12    utils::*,
13};
14
15/// Our D-Bus deserialization implementation.
16#[derive(Debug)]
17pub(crate) struct Deserializer<'de, 'sig, 'f, F>(pub(crate) DeserializerCommon<'de, 'sig, 'f, F>);
18
19#[allow(clippy::needless_lifetimes)]
20impl<'de, 'sig, 'f, F> Deserializer<'de, 'sig, 'f, F> {
21    /// Create a Deserializer struct instance.
22    ///
23    /// On Windows, there is no `fds` argument.
24    pub fn new<'r: 'de>(
25        bytes: &'r [u8],
26        #[cfg(unix)] fds: Option<&'f [F]>,
27        signature: &'sig Signature,
28        ctxt: Context,
29    ) -> Result<Self> {
30        assert_eq!(ctxt.format(), Format::DBus);
31
32        Ok(Self(DeserializerCommon {
33            ctxt,
34            signature,
35            bytes,
36            #[cfg(unix)]
37            fds,
38            #[cfg(not(unix))]
39            fds: PhantomData,
40            pos: 0,
41            container_depths: Default::default(),
42        }))
43    }
44}
45
46macro_rules! deserialize_basic {
47    ($method:ident $read_method:ident $visitor_method:ident($type:ty)) => {
48        fn $method<V>(self, visitor: V) -> Result<V::Value>
49        where
50            V: Visitor<'de>,
51        {
52            let v = self
53                .0
54                .ctxt
55                .endian()
56                .$read_method(self.0.next_const_size_slice::<$type>()?);
57
58            visitor.$visitor_method(v)
59        }
60    };
61}
62
63macro_rules! deserialize_as {
64    ($method:ident => $as:ident) => {
65        deserialize_as!($method() => $as());
66    };
67    ($method:ident($($in_arg:ident: $type:ty),*) => $as:ident($($as_arg:expr),*)) => {
68        #[inline]
69        fn $method<V>(self, $($in_arg: $type,)* visitor: V) -> Result<V::Value>
70        where
71            V: Visitor<'de>,
72        {
73            self.$as($($as_arg,)* visitor)
74        }
75    }
76}
77
78impl<'de, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F> de::Deserializer<'de>
79    for &mut Deserializer<'de, '_, '_, F>
80{
81    type Error = Error;
82
83    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
84    where
85        V: Visitor<'de>,
86    {
87        crate::de::deserialize_any::<Self, V>(self, self.0.signature, visitor)
88    }
89
90    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
91    where
92        V: Visitor<'de>,
93    {
94        let v = self
95            .0
96            .ctxt
97            .endian()
98            .read_u32(self.0.next_const_size_slice::<bool>()?);
99        let b = match v {
100            1 => true,
101            0 => false,
102            // As per D-Bus spec, only 0 and 1 values are allowed
103            _ => {
104                return Err(de::Error::invalid_value(
105                    de::Unexpected::Unsigned(v as u64),
106                    &"0 or 1",
107                ));
108            }
109        };
110
111        visitor.visit_bool(b)
112    }
113
114    fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
115    where
116        V: Visitor<'de>,
117    {
118        self.deserialize_i16(visitor)
119    }
120
121    deserialize_basic!(deserialize_i16 read_i16 visit_i16(i16));
122    deserialize_basic!(deserialize_i64 read_i64 visit_i64(i64));
123    deserialize_basic!(deserialize_u16 read_u16 visit_u16(u16));
124    deserialize_basic!(deserialize_u32 read_u32 visit_u32(u32));
125    deserialize_basic!(deserialize_u64 read_u64 visit_u64(u64));
126    deserialize_basic!(deserialize_f64 read_f64 visit_f64(f64));
127
128    fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
129    where
130        V: Visitor<'de>,
131    {
132        let bytes = deserialize_ay(self)?;
133        visitor.visit_byte_buf(bytes.into())
134    }
135
136    fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
137    where
138        V: Visitor<'de>,
139    {
140        let bytes = deserialize_ay(self)?;
141        visitor.visit_borrowed_bytes(bytes)
142    }
143
144    deserialize_as!(deserialize_char => deserialize_str);
145    deserialize_as!(deserialize_string => deserialize_str);
146    deserialize_as!(deserialize_tuple(_l: usize) => deserialize_struct("", &[]));
147    deserialize_as!(deserialize_tuple_struct(n: &'static str, _l: usize) => deserialize_struct(n, &[]));
148    deserialize_as!(deserialize_struct(_n: &'static str, _f: &'static [&'static str]) => deserialize_seq());
149    deserialize_as!(deserialize_map => deserialize_seq);
150    deserialize_as!(deserialize_ignored_any => deserialize_any);
151
152    fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
153    where
154        V: Visitor<'de>,
155    {
156        let v = match &self.0.signature {
157            #[cfg(unix)]
158            Signature::Fd => {
159                let alignment = u32::alignment(Format::DBus);
160                self.0.parse_padding(alignment)?;
161                let idx = self.0.ctxt.endian().read_u32(self.0.next_slice(alignment)?);
162                self.0.get_fd(idx)?
163            }
164            _ => self
165                .0
166                .ctxt
167                .endian()
168                .read_i32(self.0.next_const_size_slice::<i32>()?),
169        };
170
171        visitor.visit_i32(v)
172    }
173
174    fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
175    where
176        V: Visitor<'de>,
177    {
178        // Endianness is irrelevant for single bytes.
179        visitor.visit_u8(self.0.next_const_size_slice::<u8>().map(|bytes| bytes[0])?)
180    }
181
182    fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
183    where
184        V: Visitor<'de>,
185    {
186        let v = self
187            .0
188            .ctxt
189            .endian()
190            .read_f64(self.0.next_const_size_slice::<f64>()?);
191
192        if v.is_finite() && v > (f32::MAX as f64) {
193            return Err(de::Error::invalid_value(
194                de::Unexpected::Float(v),
195                &"Too large for f32",
196            ));
197        }
198        visitor.visit_f32(v as f32)
199    }
200
201    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
202    where
203        V: Visitor<'de>,
204    {
205        let len = match self.0.signature {
206            Signature::Signature | Signature::Variant => {
207                let len_slice = self.0.next_slice(1)?;
208
209                len_slice[0] as usize
210            }
211            Signature::Str | Signature::ObjectPath => {
212                let alignment = u32::alignment(Format::DBus);
213                self.0.parse_padding(alignment)?;
214                let len_slice = self.0.next_slice(alignment)?;
215
216                self.0.ctxt.endian().read_u32(len_slice) as usize
217            }
218            _ => {
219                let expected = format!(
220                    "`{}`, `{}`, `{}` or `{}`",
221                    <&str>::SIGNATURE_STR,
222                    Signature::SIGNATURE_STR,
223                    ObjectPath::SIGNATURE_STR,
224                    VARIANT_SIGNATURE_CHAR,
225                );
226                return Err(Error::SignatureMismatch(self.0.signature.clone(), expected));
227            }
228        };
229        let slice = self.0.next_slice(len)?;
230        if slice.contains(&0) {
231            return Err(serde::de::Error::invalid_value(
232                serde::de::Unexpected::Char('\0'),
233                &"D-Bus string type must not contain interior null bytes",
234            ));
235        }
236        self.0.pos += 1; // skip trailing null byte
237        let s = str::from_utf8(slice).map_err(Error::Utf8)?;
238
239        visitor.visit_borrowed_str(s)
240    }
241
242    fn deserialize_option<V>(self, #[allow(unused)] visitor: V) -> Result<V::Value>
243    where
244        V: Visitor<'de>,
245    {
246        #[cfg(feature = "option-as-array")]
247        {
248            // This takes care of parsing all the padding and getting the byte length.
249            let ad = ArrayDeserializer::new(self)?;
250            let len = ad.len;
251            let array_signature = ad.array_signature;
252
253            let v = if len == 0 {
254                visitor.visit_none()
255            } else {
256                visitor.visit_some(&mut *self)
257            };
258            self.0.container_depths = self.0.container_depths.dec_array();
259            self.0.signature = array_signature;
260
261            v
262        }
263
264        #[cfg(not(feature = "option-as-array"))]
265        Err(de::Error::custom(
266            "Can only decode Option<T> from D-Bus format if `option-as-array` feature is enabled",
267        ))
268    }
269
270    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
271    where
272        V: Visitor<'de>,
273    {
274        visitor.visit_unit()
275    }
276
277    fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
278    where
279        V: Visitor<'de>,
280    {
281        visitor.visit_unit()
282    }
283
284    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
285    where
286        V: Visitor<'de>,
287    {
288        visitor.visit_newtype_struct(self)
289    }
290
291    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
292    where
293        V: Visitor<'de>,
294    {
295        let alignment = self.0.signature.alignment(Format::DBus);
296        self.0.parse_padding(alignment)?;
297
298        match self.0.signature {
299            Signature::Variant => {
300                let value_de = ValueDeserializer::new(self);
301
302                visitor.visit_seq(value_de)
303            }
304            Signature::Array(_) => {
305                let array_de = ArrayDeserializer::new(self)?;
306                visitor.visit_seq(ArraySeqDeserializer(array_de))
307            }
308            Signature::Dict { .. } => visitor.visit_map(ArrayMapDeserializer::new(self)?),
309            Signature::Structure(_) => visitor.visit_seq(StructureDeserializer::new(self)?),
310            Signature::U8 => {
311                // Empty struct: encoded as a `0u8`.
312                let _: u8 = serde::Deserialize::deserialize(&mut *self)?;
313
314                visitor.visit_seq(StructureDeserializer {
315                    de: self,
316                    field_idx: 0,
317                    num_fields: 0,
318                })
319            }
320            _ => Err(Error::SignatureMismatch(
321                self.0.signature.clone(),
322                "a variant, array, dict, structure or u8".to_string(),
323            )),
324        }
325    }
326
327    fn deserialize_enum<V>(
328        self,
329        name: &'static str,
330        _variants: &'static [&'static str],
331        visitor: V,
332    ) -> Result<V::Value>
333    where
334        V: Visitor<'de>,
335    {
336        let alignment = self.0.signature.alignment(self.0.ctxt.format());
337        self.0.parse_padding(alignment)?;
338
339        visitor.visit_enum(crate::de::Enum {
340            de: self,
341            name,
342            _phantom: PhantomData,
343        })
344    }
345
346    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
347    where
348        V: Visitor<'de>,
349    {
350        match self.0.signature {
351            Signature::Str | Signature::ObjectPath | Signature::Signature => {
352                self.deserialize_str(visitor)
353            }
354            Signature::U32 => self.deserialize_u32(visitor),
355            Signature::Structure(fields) => {
356                let mut fields = fields.iter();
357                let index_signature = fields.next().ok_or_else(|| {
358                    Error::SignatureMismatch(
359                        self.0.signature.clone(),
360                        "a structure with 2 fields and u32 as its first field".to_string(),
361                    )
362                })?;
363                self.0.signature = index_signature;
364                let v = self.deserialize_u32(visitor);
365
366                self.0.signature = fields.next().ok_or_else(|| {
367                    Error::SignatureMismatch(
368                        self.0.signature.clone(),
369                        "a structure with 2 fields and u32 as its first field".to_string(),
370                    )
371                })?;
372
373                v
374            }
375            _ => Err(Error::SignatureMismatch(
376                self.0.signature.clone(),
377                "a string, object path or signature".to_string(),
378            )),
379        }
380    }
381
382    fn is_human_readable(&self) -> bool {
383        false
384    }
385}
386
387struct ArrayDeserializer<'d, 'de, 'sig, 'f, F> {
388    de: &'d mut Deserializer<'de, 'sig, 'f, F>,
389    len: usize,
390    start: usize,
391    // alignment of element
392    element_alignment: usize,
393    array_signature: &'sig Signature,
394}
395
396impl<'d, 'de, 'sig, 'f, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F>
397    ArrayDeserializer<'d, 'de, 'sig, 'f, F>
398{
399    fn new(de: &'d mut Deserializer<'de, 'sig, 'f, F>) -> Result<Self> {
400        de.0.parse_padding(ARRAY_ALIGNMENT_DBUS)?;
401        de.0.container_depths = de.0.container_depths.inc_array()?;
402
403        let len = de.0.ctxt.endian().read_u32(de.0.next_slice(4)?) as usize;
404
405        // D-Bus expects us to add padding for the first element even when there is no first
406        // element (i-e empty array) so we parse padding already.
407        let (element_alignment, child_signature) = match de.0.signature {
408            Signature::Array(child) => (child.alignment(de.0.ctxt.format()), child.signature()),
409            Signature::Dict { key, .. } => (DICT_ENTRY_ALIGNMENT_DBUS, key.signature()),
410            _ => {
411                return Err(Error::SignatureMismatch(
412                    de.0.signature.clone(),
413                    "an array or dict".to_string(),
414                ));
415            }
416        };
417        de.0.parse_padding(element_alignment)?;
418
419        // In case of an array, we'll only be serializing the array's child elements from now on and
420        // in case of a dict, we'll swap key and value signatures during serlization of each entry,
421        // so let's assume the element signature for array and key signature for dict, from now on.
422        // We restore the original signature at the end of deserialization.
423        let array_signature = de.0.signature;
424        de.0.signature = child_signature;
425        let start = de.0.pos;
426
427        Ok(Self {
428            de,
429            len,
430            start,
431            element_alignment,
432            array_signature,
433        })
434    }
435
436    fn next<T>(&mut self, seed: T) -> Result<T::Value>
437    where
438        T: DeserializeSeed<'de>,
439    {
440        let v = seed.deserialize(&mut *self.de);
441
442        if self.de.0.pos > self.start + self.len {
443            return Err(serde::de::Error::invalid_length(
444                self.len,
445                &format!(">= {}", self.de.0.pos - self.start).as_str(),
446            ));
447        }
448
449        v
450    }
451
452    fn next_element<T>(&mut self, seed: T) -> Result<Option<T::Value>>
453    where
454        T: DeserializeSeed<'de>,
455    {
456        if self.done() {
457            self.end();
458
459            return Ok(None);
460        }
461        // Redundant for normal arrays but dict requires each entry to be padded by 8 bytes.
462        self.de.0.parse_padding(self.element_alignment)?;
463
464        self.next(seed).map(Some)
465    }
466
467    fn done(&self) -> bool {
468        self.de.0.pos == self.start + self.len
469    }
470
471    fn end(&mut self) {
472        self.de.0.container_depths = self.de.0.container_depths.dec_array();
473        self.de.0.signature = self.array_signature;
474    }
475}
476
477fn deserialize_ay<'de, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F>(
478    de: &mut Deserializer<'de, '_, '_, F>,
479) -> Result<&'de [u8]> {
480    if !matches!(de.0.signature, Signature::Array(child) if child.signature() == &Signature::U8) {
481        return Err(de::Error::invalid_type(de::Unexpected::Seq, &"ay"));
482    }
483
484    let mut ad = ArrayDeserializer::new(de)?;
485    let len = ad.len;
486    ad.end();
487
488    de.0.next_slice(len)
489}
490
491struct ArraySeqDeserializer<'d, 'de, 'sig, 'f, F>(ArrayDeserializer<'d, 'de, 'sig, 'f, F>);
492
493impl<'de, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F> SeqAccess<'de>
494    for ArraySeqDeserializer<'_, 'de, '_, '_, F>
495{
496    type Error = Error;
497
498    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
499    where
500        T: DeserializeSeed<'de>,
501    {
502        self.0.next_element(seed)
503    }
504}
505
506struct ArrayMapDeserializer<'d, 'de, 'sig, 'f, F> {
507    ad: ArrayDeserializer<'d, 'de, 'sig, 'f, F>,
508    key_signature: &'sig Signature,
509    value_signature: &'sig Signature,
510}
511impl<'d, 'de, 'sig, 'f, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F>
512    ArrayMapDeserializer<'d, 'de, 'sig, 'f, F>
513{
514    fn new(de: &'d mut Deserializer<'de, 'sig, 'f, F>) -> Result<Self> {
515        let (key_signature, value_signature) = match de.0.signature {
516            Signature::Dict { key, value } => (key.signature(), value.signature()),
517            _ => {
518                return Err(Error::SignatureMismatch(
519                    de.0.signature.clone(),
520                    "a dict".to_string(),
521                ));
522            }
523        };
524        let ad = ArrayDeserializer::new(de)?;
525
526        Ok(Self {
527            ad,
528            key_signature,
529            value_signature,
530        })
531    }
532}
533
534impl<'de, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F> MapAccess<'de>
535    for ArrayMapDeserializer<'_, 'de, '_, '_, F>
536{
537    type Error = Error;
538
539    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
540    where
541        K: DeserializeSeed<'de>,
542    {
543        self.ad.next_element(seed)
544    }
545
546    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
547    where
548        V: DeserializeSeed<'de>,
549    {
550        self.ad.de.0.signature = self.value_signature;
551        let v = self.ad.next(seed);
552        self.ad.de.0.signature = self.key_signature;
553
554        v
555    }
556}
557
558#[derive(Debug)]
559struct StructureDeserializer<'d, 'de, 'sig, 'f, F> {
560    de: &'d mut Deserializer<'de, 'sig, 'f, F>,
561    /// Index of the next field to serialize.
562    field_idx: usize,
563    /// The number of fields in the structure.
564    num_fields: usize,
565}
566
567impl<'d, 'de, 'sig, 'f, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F>
568    StructureDeserializer<'d, 'de, 'sig, 'f, F>
569{
570    fn new(de: &'d mut Deserializer<'de, 'sig, 'f, F>) -> Result<Self> {
571        let num_fields = match de.0.signature {
572            Signature::Structure(fields) => fields.iter().count(),
573            _ => unreachable!("Incorrect signature for struct"),
574        };
575        de.0.parse_padding(STRUCT_ALIGNMENT_DBUS)?;
576        de.0.container_depths = de.0.container_depths.inc_structure()?;
577
578        Ok(Self {
579            de,
580            field_idx: 0,
581            num_fields,
582        })
583    }
584}
585
586impl<'de, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F> SeqAccess<'de>
587    for StructureDeserializer<'_, 'de, '_, '_, F>
588{
589    type Error = Error;
590
591    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
592    where
593        T: DeserializeSeed<'de>,
594    {
595        if self.field_idx == self.num_fields {
596            return Ok(None);
597        }
598
599        let signature = self.de.0.signature;
600        let field_signature = match signature {
601            Signature::Structure(fields) => {
602                let signature = fields.iter().nth(self.field_idx).ok_or_else(|| {
603                    Error::SignatureMismatch(signature.clone(), "a struct".to_string())
604                })?;
605                self.field_idx += 1;
606
607                signature
608            }
609            _ => unreachable!("Incorrect signature for struct"),
610        };
611
612        let mut de = Deserializer::<F>(DeserializerCommon {
613            ctxt: self.de.0.ctxt,
614            signature: field_signature,
615            fds: self.de.0.fds,
616            bytes: self.de.0.bytes,
617            pos: self.de.0.pos,
618            container_depths: self.de.0.container_depths,
619        });
620        let v = seed.deserialize(&mut de)?;
621        self.de.0.pos = de.0.pos;
622
623        if self.field_idx == self.num_fields {
624            // All fields have been deserialized.
625            self.de.0.container_depths = self.de.0.container_depths.dec_structure();
626        }
627
628        Ok(Some(v))
629    }
630}
631
632#[derive(Debug)]
633struct ValueDeserializer<'d, 'de, 'sig, 'f, F> {
634    de: &'d mut Deserializer<'de, 'sig, 'f, F>,
635    stage: ValueParseStage,
636    sig_start: usize,
637}
638
639impl<'d, 'de, 'sig, 'f, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F>
640    ValueDeserializer<'d, 'de, 'sig, 'f, F>
641{
642    fn new(de: &'d mut Deserializer<'de, 'sig, 'f, F>) -> Self {
643        let sig_start = de.0.pos;
644        ValueDeserializer::<F> {
645            de,
646            stage: ValueParseStage::Signature,
647            sig_start,
648        }
649    }
650}
651
652impl<'de, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F> SeqAccess<'de>
653    for ValueDeserializer<'_, 'de, '_, '_, F>
654{
655    type Error = Error;
656
657    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
658    where
659        T: DeserializeSeed<'de>,
660    {
661        match self.stage {
662            ValueParseStage::Signature => {
663                self.stage = ValueParseStage::Value;
664
665                let signature = self.de.0.signature;
666                self.de.0.signature = &Signature::Signature;
667                let ret = seed.deserialize(&mut *self.de).map(Some);
668                self.de.0.signature = signature;
669
670                ret
671            }
672            ValueParseStage::Value => {
673                self.stage = ValueParseStage::Done;
674
675                let sig_len = self.de.0.bytes[self.sig_start] as usize;
676                // skip length byte
677                let sig_start = self.sig_start + 1;
678                let sig_end = sig_start + sig_len;
679                // Skip trailing nul byte
680                let value_start = sig_end + 1;
681
682                let slice = subslice(self.de.0.bytes, sig_start..sig_end)?;
683                let signature = Signature::from_bytes(slice)?;
684
685                let ctxt = Context::new(
686                    Format::DBus,
687                    self.de.0.ctxt.endian(),
688                    self.de.0.ctxt.position() + value_start,
689                );
690                let mut de = Deserializer::<F>(DeserializerCommon {
691                    ctxt,
692                    signature: &signature,
693                    bytes: subslice(self.de.0.bytes, value_start..)?,
694                    fds: self.de.0.fds,
695                    pos: 0,
696                    container_depths: self.de.0.container_depths.inc_variant()?,
697                });
698
699                let v = seed.deserialize(&mut de).map(Some);
700                self.de.0.pos += de.0.pos;
701
702                v
703            }
704            ValueParseStage::Done => Ok(None),
705        }
706    }
707}
708
709impl<'de, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F> EnumAccess<'de>
710    for crate::de::Enum<&mut Deserializer<'de, '_, '_, F>, F>
711{
712    type Error = Error;
713    type Variant = Self;
714
715    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
716    where
717        V: DeserializeSeed<'de>,
718    {
719        seed.deserialize(&mut *self.de).map(|v| (v, self))
720    }
721}