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    de::{DeserializerCommon, ValueParseStage},
10    serialized::{Context, Format},
11    utils::*,
12    Basic, Error, ObjectPath, Result, Signature,
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 => self.deserialize_str(visitor),
352            Signature::U32 => self.deserialize_u32(visitor),
353            Signature::Structure(fields) => {
354                let mut fields = fields.iter();
355                let index_signature = fields.next().ok_or_else(|| {
356                    Error::SignatureMismatch(
357                        self.0.signature.clone(),
358                        "a structure with 2 fields and u32 as its first field".to_string(),
359                    )
360                })?;
361                self.0.signature = index_signature;
362                let v = self.deserialize_u32(visitor);
363
364                self.0.signature = fields.next().ok_or_else(|| {
365                    Error::SignatureMismatch(
366                        self.0.signature.clone(),
367                        "a structure with 2 fields and u32 as its first field".to_string(),
368                    )
369                })?;
370
371                v
372            }
373            _ => Err(Error::SignatureMismatch(
374                self.0.signature.clone(),
375                "a string, object path or signature".to_string(),
376            )),
377        }
378    }
379
380    fn is_human_readable(&self) -> bool {
381        false
382    }
383}
384
385struct ArrayDeserializer<'d, 'de, 'sig, 'f, F> {
386    de: &'d mut Deserializer<'de, 'sig, 'f, F>,
387    len: usize,
388    start: usize,
389    // alignment of element
390    element_alignment: usize,
391    array_signature: &'sig Signature,
392}
393
394impl<'d, 'de, 'sig, 'f, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F>
395    ArrayDeserializer<'d, 'de, 'sig, 'f, F>
396{
397    fn new(de: &'d mut Deserializer<'de, 'sig, 'f, F>) -> Result<Self> {
398        de.0.parse_padding(ARRAY_ALIGNMENT_DBUS)?;
399        de.0.container_depths = de.0.container_depths.inc_array()?;
400
401        let len = de.0.ctxt.endian().read_u32(de.0.next_slice(4)?) as usize;
402
403        // D-Bus expects us to add padding for the first element even when there is no first
404        // element (i-e empty array) so we parse padding already.
405        let (element_alignment, child_signature) = match de.0.signature {
406            Signature::Array(child) => (child.alignment(de.0.ctxt.format()), child.signature()),
407            Signature::Dict { key, .. } => (DICT_ENTRY_ALIGNMENT_DBUS, key.signature()),
408            _ => {
409                return Err(Error::SignatureMismatch(
410                    de.0.signature.clone(),
411                    "an array or dict".to_string(),
412                ));
413            }
414        };
415        de.0.parse_padding(element_alignment)?;
416
417        // In case of an array, we'll only be serializing the array's child elements from now on and
418        // in case of a dict, we'll swap key and value signatures during serlization of each entry,
419        // so let's assume the element signature for array and key signature for dict, from now on.
420        // We restore the original signature at the end of deserialization.
421        let array_signature = de.0.signature;
422        de.0.signature = child_signature;
423        let start = de.0.pos;
424
425        Ok(Self {
426            de,
427            len,
428            start,
429            element_alignment,
430            array_signature,
431        })
432    }
433
434    fn next<T>(&mut self, seed: T) -> Result<T::Value>
435    where
436        T: DeserializeSeed<'de>,
437    {
438        let v = seed.deserialize(&mut *self.de);
439
440        if self.de.0.pos > self.start + self.len {
441            return Err(serde::de::Error::invalid_length(
442                self.len,
443                &format!(">= {}", self.de.0.pos - self.start).as_str(),
444            ));
445        }
446
447        v
448    }
449
450    fn next_element<T>(&mut self, seed: T) -> Result<Option<T::Value>>
451    where
452        T: DeserializeSeed<'de>,
453    {
454        if self.done() {
455            self.end();
456
457            return Ok(None);
458        }
459        // Redundant for normal arrays but dict requires each entry to be padded by 8 bytes.
460        self.de.0.parse_padding(self.element_alignment)?;
461
462        self.next(seed).map(Some)
463    }
464
465    fn done(&self) -> bool {
466        self.de.0.pos == self.start + self.len
467    }
468
469    fn end(&mut self) {
470        self.de.0.container_depths = self.de.0.container_depths.dec_array();
471        self.de.0.signature = self.array_signature;
472    }
473}
474
475fn deserialize_ay<'de, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F>(
476    de: &mut Deserializer<'de, '_, '_, F>,
477) -> Result<&'de [u8]> {
478    if !matches!(de.0.signature, Signature::Array(child) if child.signature() == &Signature::U8) {
479        return Err(de::Error::invalid_type(de::Unexpected::Seq, &"ay"));
480    }
481
482    let mut ad = ArrayDeserializer::new(de)?;
483    let len = ad.len;
484    ad.end();
485
486    de.0.next_slice(len)
487}
488
489struct ArraySeqDeserializer<'d, 'de, 'sig, 'f, F>(ArrayDeserializer<'d, 'de, 'sig, 'f, F>);
490
491impl<'de, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F> SeqAccess<'de>
492    for ArraySeqDeserializer<'_, 'de, '_, '_, F>
493{
494    type Error = Error;
495
496    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
497    where
498        T: DeserializeSeed<'de>,
499    {
500        self.0.next_element(seed)
501    }
502}
503
504struct ArrayMapDeserializer<'d, 'de, 'sig, 'f, F> {
505    ad: ArrayDeserializer<'d, 'de, 'sig, 'f, F>,
506    key_signature: &'sig Signature,
507    value_signature: &'sig Signature,
508}
509impl<'d, 'de, 'sig, 'f, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F>
510    ArrayMapDeserializer<'d, 'de, 'sig, 'f, F>
511{
512    fn new(de: &'d mut Deserializer<'de, 'sig, 'f, F>) -> Result<Self> {
513        let (key_signature, value_signature) = match de.0.signature {
514            Signature::Dict { key, value } => (key.signature(), value.signature()),
515            _ => {
516                return Err(Error::SignatureMismatch(
517                    de.0.signature.clone(),
518                    "a dict".to_string(),
519                ));
520            }
521        };
522        let ad = ArrayDeserializer::new(de)?;
523
524        Ok(Self {
525            ad,
526            key_signature,
527            value_signature,
528        })
529    }
530}
531
532impl<'de, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F> MapAccess<'de>
533    for ArrayMapDeserializer<'_, 'de, '_, '_, F>
534{
535    type Error = Error;
536
537    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
538    where
539        K: DeserializeSeed<'de>,
540    {
541        self.ad.next_element(seed)
542    }
543
544    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
545    where
546        V: DeserializeSeed<'de>,
547    {
548        self.ad.de.0.signature = self.value_signature;
549        let v = self.ad.next(seed);
550        self.ad.de.0.signature = self.key_signature;
551
552        v
553    }
554}
555
556#[derive(Debug)]
557struct StructureDeserializer<'d, 'de, 'sig, 'f, F> {
558    de: &'d mut Deserializer<'de, 'sig, 'f, F>,
559    /// Index of the next field to serialize.
560    field_idx: usize,
561    /// The number of fields in the structure.
562    num_fields: usize,
563}
564
565impl<'d, 'de, 'sig, 'f, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F>
566    StructureDeserializer<'d, 'de, 'sig, 'f, F>
567{
568    fn new(de: &'d mut Deserializer<'de, 'sig, 'f, F>) -> Result<Self> {
569        let num_fields = match de.0.signature {
570            Signature::Structure(fields) => fields.iter().count(),
571            _ => unreachable!("Incorrect signature for struct"),
572        };
573        de.0.parse_padding(STRUCT_ALIGNMENT_DBUS)?;
574        de.0.container_depths = de.0.container_depths.inc_structure()?;
575
576        Ok(Self {
577            de,
578            field_idx: 0,
579            num_fields,
580        })
581    }
582}
583
584impl<'de, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F> SeqAccess<'de>
585    for StructureDeserializer<'_, 'de, '_, '_, F>
586{
587    type Error = Error;
588
589    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
590    where
591        T: DeserializeSeed<'de>,
592    {
593        if self.field_idx == self.num_fields {
594            return Ok(None);
595        }
596
597        let signature = self.de.0.signature;
598        let field_signature = match signature {
599            Signature::Structure(fields) => {
600                let signature = fields.iter().nth(self.field_idx).ok_or_else(|| {
601                    Error::SignatureMismatch(signature.clone(), "a struct".to_string())
602                })?;
603                self.field_idx += 1;
604
605                signature
606            }
607            _ => unreachable!("Incorrect signature for struct"),
608        };
609
610        let mut de = Deserializer::<F>(DeserializerCommon {
611            ctxt: self.de.0.ctxt,
612            signature: field_signature,
613            fds: self.de.0.fds,
614            bytes: self.de.0.bytes,
615            pos: self.de.0.pos,
616            container_depths: self.de.0.container_depths,
617        });
618        let v = seed.deserialize(&mut de)?;
619        self.de.0.pos = de.0.pos;
620
621        if self.field_idx == self.num_fields {
622            // All fields have been deserialized.
623            self.de.0.container_depths = self.de.0.container_depths.dec_structure();
624        }
625
626        Ok(Some(v))
627    }
628}
629
630#[derive(Debug)]
631struct ValueDeserializer<'d, 'de, 'sig, 'f, F> {
632    de: &'d mut Deserializer<'de, 'sig, 'f, F>,
633    stage: ValueParseStage,
634    sig_start: usize,
635}
636
637impl<'d, 'de, 'sig, 'f, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F>
638    ValueDeserializer<'d, 'de, 'sig, 'f, F>
639{
640    fn new(de: &'d mut Deserializer<'de, 'sig, 'f, F>) -> Self {
641        let sig_start = de.0.pos;
642        ValueDeserializer::<F> {
643            de,
644            stage: ValueParseStage::Signature,
645            sig_start,
646        }
647    }
648}
649
650impl<'de, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F> SeqAccess<'de>
651    for ValueDeserializer<'_, 'de, '_, '_, F>
652{
653    type Error = Error;
654
655    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
656    where
657        T: DeserializeSeed<'de>,
658    {
659        match self.stage {
660            ValueParseStage::Signature => {
661                self.stage = ValueParseStage::Value;
662
663                let signature = self.de.0.signature;
664                self.de.0.signature = &Signature::Signature;
665                let ret = seed.deserialize(&mut *self.de).map(Some);
666                self.de.0.signature = signature;
667
668                ret
669            }
670            ValueParseStage::Value => {
671                self.stage = ValueParseStage::Done;
672
673                let sig_len = self.de.0.bytes[self.sig_start] as usize;
674                // skip length byte
675                let sig_start = self.sig_start + 1;
676                let sig_end = sig_start + sig_len;
677                // Skip trailing nul byte
678                let value_start = sig_end + 1;
679
680                let slice = subslice(self.de.0.bytes, sig_start..sig_end)?;
681                let signature = Signature::from_bytes(slice)?;
682
683                let ctxt = Context::new(
684                    Format::DBus,
685                    self.de.0.ctxt.endian(),
686                    self.de.0.ctxt.position() + value_start,
687                );
688                let mut de = Deserializer::<F>(DeserializerCommon {
689                    ctxt,
690                    signature: &signature,
691                    bytes: subslice(self.de.0.bytes, value_start..)?,
692                    fds: self.de.0.fds,
693                    pos: 0,
694                    container_depths: self.de.0.container_depths.inc_variant()?,
695                });
696
697                let v = seed.deserialize(&mut de).map(Some);
698                self.de.0.pos += de.0.pos;
699
700                v
701            }
702            ValueParseStage::Done => Ok(None),
703        }
704    }
705}
706
707impl<'de, #[cfg(unix)] F: AsFd, #[cfg(not(unix))] F> EnumAccess<'de>
708    for crate::de::Enum<&mut Deserializer<'de, '_, '_, F>, F>
709{
710    type Error = Error;
711    type Variant = Self;
712
713    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
714    where
715        V: DeserializeSeed<'de>,
716    {
717        seed.deserialize(&mut *self.de).map(|v| (v, self))
718    }
719}