zvariant/dbus/
de.rs

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