1use serde::{
2 de::{self, DeserializeSeed, VariantAccess, Visitor},
3 Deserialize,
4};
5use static_assertions::assert_impl_all;
6
7use std::{marker::PhantomData, str};
8
9#[cfg(unix)]
10use std::os::unix::io::RawFd;
11
12#[cfg(feature = "gvariant")]
13use crate::gvariant::Deserializer as GVDeserializer;
14use crate::{
15 container_depths::ContainerDepths, dbus::Deserializer as DBusDeserializer,
16 signature_parser::SignatureParser, utils::*, Basic, DynamicDeserialize, DynamicType,
17 EncodingContext, EncodingFormat, Error, ObjectPath, Result, Signature, Type,
18};
19
20#[cfg(unix)]
21use crate::Fd;
22
23#[cfg(unix)]
45pub fn from_slice_fds<'d, 'r: 'd, B, T: ?Sized>(
46 bytes: &'r [u8],
47 fds: Option<&[RawFd]>,
48 ctxt: EncodingContext<B>,
49) -> Result<T>
50where
51 B: byteorder::ByteOrder,
52 T: Deserialize<'d> + Type,
53{
54 let signature = T::signature();
55 from_slice_fds_for_signature(bytes, fds, ctxt, &signature)
56}
57
58pub fn from_slice<'d, 'r: 'd, B, T: ?Sized>(bytes: &'r [u8], ctxt: EncodingContext<B>) -> Result<T>
77where
78 B: byteorder::ByteOrder,
79 T: Deserialize<'d> + Type,
80{
81 let signature = T::signature();
82 from_slice_for_signature(bytes, ctxt, &signature)
83}
84
85pub fn from_slice_for_signature<'d, 'r: 'd, B, T: ?Sized>(
156 bytes: &'r [u8],
157 ctxt: EncodingContext<B>,
158 signature: &Signature<'_>,
159) -> Result<T>
160where
161 B: byteorder::ByteOrder,
162 T: Deserialize<'d>,
163{
164 _from_slice_fds_for_signature(
165 bytes,
166 #[cfg(unix)]
167 None,
168 ctxt,
169 signature,
170 )
171}
172
173#[cfg(unix)]
186pub fn from_slice_fds_for_signature<'d, 'r: 'd, B, T: ?Sized>(
187 bytes: &'r [u8],
188 fds: Option<&[RawFd]>,
189 ctxt: EncodingContext<B>,
190 signature: &Signature<'_>,
191) -> Result<T>
192where
193 B: byteorder::ByteOrder,
194 T: Deserialize<'d>,
195{
196 _from_slice_fds_for_signature(bytes, fds, ctxt, signature)
197}
198
199fn _from_slice_fds_for_signature<'d, 'r: 'd, B, T: ?Sized>(
200 bytes: &'r [u8],
201 #[cfg(unix)] fds: Option<&[RawFd]>,
202 ctxt: EncodingContext<B>,
203 signature: &Signature<'_>,
204) -> Result<T>
205where
206 B: byteorder::ByteOrder,
207 T: Deserialize<'d>,
208{
209 let mut de = match ctxt.format() {
210 #[cfg(feature = "gvariant")]
211 EncodingFormat::GVariant => Deserializer::GVariant(GVDeserializer::new(
212 bytes,
213 #[cfg(unix)]
214 fds,
215 signature,
216 ctxt,
217 )),
218 EncodingFormat::DBus => Deserializer::DBus(DBusDeserializer::new(
219 bytes,
220 #[cfg(unix)]
221 fds,
222 signature,
223 ctxt,
224 )),
225 };
226
227 T::deserialize(&mut de)
228}
229
230pub fn from_slice_for_dynamic_signature<'d, B, T>(
237 bytes: &'d [u8],
238 ctxt: EncodingContext<B>,
239 signature: &Signature<'d>,
240) -> Result<T>
241where
242 B: byteorder::ByteOrder,
243 T: DynamicDeserialize<'d>,
244{
245 let seed = T::deserializer_for_signature(signature)?;
246
247 from_slice_with_seed(bytes, ctxt, seed)
248}
249
250#[cfg(unix)]
259pub fn from_slice_fds_for_dynamic_signature<'d, B, T>(
260 bytes: &'d [u8],
261 fds: Option<&[RawFd]>,
262 ctxt: EncodingContext<B>,
263 signature: &Signature<'d>,
264) -> Result<T>
265where
266 B: byteorder::ByteOrder,
267 T: DynamicDeserialize<'d>,
268{
269 let seed = T::deserializer_for_signature(signature)?;
270
271 from_slice_fds_with_seed(bytes, fds, ctxt, seed)
272}
273
274pub fn from_slice_with_seed<'d, B, S>(
281 bytes: &'d [u8],
282 ctxt: EncodingContext<B>,
283 seed: S,
284) -> Result<S::Value>
285where
286 B: byteorder::ByteOrder,
287 S: DeserializeSeed<'d> + DynamicType,
288{
289 _from_slice_fds_with_seed(
290 bytes,
291 #[cfg(unix)]
292 None,
293 ctxt,
294 seed,
295 )
296}
297
298#[cfg(unix)]
307pub fn from_slice_fds_with_seed<'d, B, S>(
308 bytes: &'d [u8],
309 fds: Option<&[RawFd]>,
310 ctxt: EncodingContext<B>,
311 seed: S,
312) -> Result<S::Value>
313where
314 B: byteorder::ByteOrder,
315 S: DeserializeSeed<'d> + DynamicType,
316{
317 _from_slice_fds_with_seed(bytes, fds, ctxt, seed)
318}
319
320fn _from_slice_fds_with_seed<'d, B, S>(
321 bytes: &'d [u8],
322 #[cfg(unix)] fds: Option<&[RawFd]>,
323 ctxt: EncodingContext<B>,
324 seed: S,
325) -> Result<S::Value>
326where
327 B: byteorder::ByteOrder,
328 S: DeserializeSeed<'d> + DynamicType,
329{
330 let signature = S::dynamic_signature(&seed).to_owned();
331
332 let mut de = match ctxt.format() {
333 #[cfg(feature = "gvariant")]
334 EncodingFormat::GVariant => Deserializer::GVariant(GVDeserializer::new(
335 bytes,
336 #[cfg(unix)]
337 fds,
338 &signature,
339 ctxt,
340 )),
341 EncodingFormat::DBus => Deserializer::DBus(DBusDeserializer::new(
342 bytes,
343 #[cfg(unix)]
344 fds,
345 &signature,
346 ctxt,
347 )),
348 };
349
350 seed.deserialize(&mut de)
351}
352
353#[derive(Debug)]
355pub(crate) struct DeserializerCommon<'de, 'sig, 'f, B> {
356 pub(crate) ctxt: EncodingContext<B>,
357 pub(crate) bytes: &'de [u8],
358
359 #[cfg(unix)]
360 pub(crate) fds: Option<&'f [RawFd]>,
361 #[cfg(not(unix))]
362 pub(crate) fds: PhantomData<&'f ()>,
363
364 pub(crate) pos: usize,
365
366 pub(crate) sig_parser: SignatureParser<'sig>,
367
368 pub(crate) container_depths: ContainerDepths,
369
370 pub(crate) b: PhantomData<B>,
371}
372
373pub enum Deserializer<'ser, 'sig, 'f, B> {
379 DBus(DBusDeserializer<'ser, 'sig, 'f, B>),
380 #[cfg(feature = "gvariant")]
381 GVariant(GVDeserializer<'ser, 'sig, 'f, B>),
382}
383
384assert_impl_all!(Deserializer<'_, '_, '_, u8>: Send, Sync, Unpin);
385
386impl<'de, 'sig, 'f, B> Deserializer<'de, 'sig, 'f, B>
387where
388 B: byteorder::ByteOrder,
389{
390 pub fn new<'r: 'de>(
394 bytes: &'r [u8],
395 #[cfg(unix)] fds: Option<&'f [RawFd]>,
396 signature: &Signature<'sig>,
397 ctxt: EncodingContext<B>,
398 ) -> Self {
399 match ctxt.format() {
400 #[cfg(feature = "gvariant")]
401 EncodingFormat::GVariant => Self::GVariant(GVDeserializer::new(
402 bytes,
403 #[cfg(unix)]
404 fds,
405 signature,
406 ctxt,
407 )),
408 EncodingFormat::DBus => Self::DBus(DBusDeserializer::new(
409 bytes,
410 #[cfg(unix)]
411 fds,
412 signature,
413 ctxt,
414 )),
415 }
416 }
417}
418
419impl<'de, 'sig, 'f, B> DeserializerCommon<'de, 'sig, 'f, B>
420where
421 B: byteorder::ByteOrder,
422{
423 #[cfg(unix)]
424 pub fn get_fd(&self, idx: u32) -> Result<i32> {
425 self.fds
426 .and_then(|fds| fds.get(idx as usize))
427 .copied()
428 .ok_or(Error::UnknownFd)
429 }
430
431 pub fn parse_padding(&mut self, alignment: usize) -> Result<usize> {
432 let padding = padding_for_n_bytes(self.abs_pos(), alignment);
433 if padding > 0 {
434 if self.pos + padding > self.bytes.len() {
435 return Err(serde::de::Error::invalid_length(
436 self.bytes.len(),
437 &format!(">= {}", self.pos + padding).as_str(),
438 ));
439 }
440
441 for i in 0..padding {
442 let byte = self.bytes[self.pos + i];
443 if byte != 0 {
444 return Err(Error::PaddingNot0(byte));
445 }
446 }
447 self.pos += padding;
448 }
449
450 Ok(padding)
451 }
452
453 pub fn prep_deserialize_basic<T>(&mut self) -> Result<()>
454 where
455 T: Basic,
456 {
457 self.sig_parser.skip_char()?;
458 self.parse_padding(T::alignment(self.ctxt.format()))?;
459
460 Ok(())
461 }
462
463 pub fn next_slice(&mut self, len: usize) -> Result<&'de [u8]> {
464 if self.pos + len > self.bytes.len() {
465 return Err(serde::de::Error::invalid_length(
466 self.bytes.len(),
467 &format!(">= {}", self.pos + len).as_str(),
468 ));
469 }
470
471 let slice = &self.bytes[self.pos..self.pos + len];
472 self.pos += len;
473
474 Ok(slice)
475 }
476
477 pub fn next_const_size_slice<T>(&mut self) -> Result<&[u8]>
478 where
479 T: Basic,
480 {
481 self.prep_deserialize_basic::<T>()?;
482
483 self.next_slice(T::alignment(self.ctxt.format()))
484 }
485
486 pub fn abs_pos(&self) -> usize {
487 self.ctxt.position() + self.pos
488 }
489}
490
491macro_rules! deserialize_method {
492 ($method:ident($($arg:ident: $type:ty),*)) => {
493 #[inline]
494 fn $method<V>(self, $($arg: $type,)* visitor: V) -> Result<V::Value>
495 where
496 V: Visitor<'de>,
497 {
498 match self {
499 #[cfg(feature = "gvariant")]
500 Deserializer::GVariant(de) => {
501 de.$method($($arg,)* visitor)
502 }
503 Deserializer::DBus(de) => {
504 de.$method($($arg,)* visitor)
505 }
506 }
507 }
508 }
509}
510
511impl<'de, 'd, 'sig, 'f, B> de::Deserializer<'de> for &'d mut Deserializer<'de, 'sig, 'f, B>
512where
513 B: byteorder::ByteOrder,
514{
515 type Error = Error;
516
517 deserialize_method!(deserialize_any());
518 deserialize_method!(deserialize_bool());
519 deserialize_method!(deserialize_i8());
520 deserialize_method!(deserialize_i16());
521 deserialize_method!(deserialize_i32());
522 deserialize_method!(deserialize_i64());
523 deserialize_method!(deserialize_u8());
524 deserialize_method!(deserialize_u16());
525 deserialize_method!(deserialize_u32());
526 deserialize_method!(deserialize_u64());
527 deserialize_method!(deserialize_f32());
528 deserialize_method!(deserialize_f64());
529 deserialize_method!(deserialize_char());
530 deserialize_method!(deserialize_str());
531 deserialize_method!(deserialize_string());
532 deserialize_method!(deserialize_bytes());
533 deserialize_method!(deserialize_byte_buf());
534 deserialize_method!(deserialize_option());
535 deserialize_method!(deserialize_unit());
536 deserialize_method!(deserialize_unit_struct(n: &'static str));
537 deserialize_method!(deserialize_newtype_struct(n: &'static str));
538 deserialize_method!(deserialize_seq());
539 deserialize_method!(deserialize_map());
540 deserialize_method!(deserialize_tuple(n: usize));
541 deserialize_method!(deserialize_tuple_struct(n: &'static str, l: usize));
542 deserialize_method!(deserialize_struct(
543 n: &'static str,
544 f: &'static [&'static str]
545 ));
546 deserialize_method!(deserialize_enum(
547 n: &'static str,
548 f: &'static [&'static str]
549 ));
550 deserialize_method!(deserialize_identifier());
551 deserialize_method!(deserialize_ignored_any());
552
553 fn is_human_readable(&self) -> bool {
554 false
555 }
556}
557
558#[derive(Debug)]
559pub(crate) enum ValueParseStage {
560 Signature,
561 Value,
562 Done,
563}
564
565pub(crate) fn deserialize_any<'de, 'sig, 'f, D, V>(
566 de: D,
567 next_char: char,
568 visitor: V,
569) -> Result<V::Value>
570where
571 D: de::Deserializer<'de, Error = Error>,
572 V: Visitor<'de>,
573{
574 match next_char {
575 u8::SIGNATURE_CHAR => de.deserialize_u8(visitor),
576 bool::SIGNATURE_CHAR => de.deserialize_bool(visitor),
577 i16::SIGNATURE_CHAR => de.deserialize_i16(visitor),
578 u16::SIGNATURE_CHAR => de.deserialize_u16(visitor),
579 i32::SIGNATURE_CHAR => de.deserialize_i32(visitor),
580 #[cfg(unix)]
581 Fd::SIGNATURE_CHAR => de.deserialize_i32(visitor),
582 u32::SIGNATURE_CHAR => de.deserialize_u32(visitor),
583 i64::SIGNATURE_CHAR => de.deserialize_i64(visitor),
584 u64::SIGNATURE_CHAR => de.deserialize_u64(visitor),
585 f64::SIGNATURE_CHAR => de.deserialize_f64(visitor),
586 <&str>::SIGNATURE_CHAR | ObjectPath::SIGNATURE_CHAR | Signature::SIGNATURE_CHAR => {
587 de.deserialize_str(visitor)
588 }
589 VARIANT_SIGNATURE_CHAR => de.deserialize_seq(visitor),
590 ARRAY_SIGNATURE_CHAR => de.deserialize_seq(visitor),
591 STRUCT_SIG_START_CHAR => de.deserialize_seq(visitor),
592 #[cfg(feature = "gvariant")]
593 MAYBE_SIGNATURE_CHAR => de.deserialize_option(visitor),
594 c => Err(de::Error::invalid_value(
595 de::Unexpected::Char(c),
596 &"a valid signature character",
597 )),
598 }
599}
600
601pub(crate) struct Enum<B, D> {
603 pub(crate) de: D,
604 pub(crate) name: &'static str,
605 pub(crate) phantom: PhantomData<B>,
606}
607
608impl<'de, B, D> VariantAccess<'de> for Enum<B, D>
609where
610 B: byteorder::ByteOrder,
611 D: de::Deserializer<'de, Error = Error>,
612{
613 type Error = Error;
614
615 fn unit_variant(self) -> std::result::Result<(), Self::Error> {
616 Ok(())
617 }
618
619 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
620 where
621 T: DeserializeSeed<'de>,
622 {
623 seed.deserialize(self.de)
624 }
625
626 fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
627 where
628 V: Visitor<'de>,
629 {
630 de::Deserializer::deserialize_struct(self.de, self.name, &[], visitor)
631 }
632
633 fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
634 where
635 V: Visitor<'de>,
636 {
637 de::Deserializer::deserialize_struct(self.de, self.name, fields, visitor)
638 }
639}