1 use serde::{ser, ser::SerializeSeq, Serialize};
2 use static_assertions::assert_impl_all;
3 use std::{
4     io::{Seek, Write},
5     marker::PhantomData,
6     os::unix::io::RawFd,
7     str,
8 };
9 
10 use crate::{
11     framing_offset_size::FramingOffsetSize, framing_offsets::FramingOffsets,
12     signature_parser::SignatureParser, utils::*, EncodingContext, EncodingFormat, Error, Result,
13     Signature,
14 };
15 
16 /// Our serialization implementation.
17 pub struct Serializer<'ser, 'sig, B, W>(pub(crate) crate::SerializerCommon<'ser, 'sig, B, W>);
18 
19 assert_impl_all!(Serializer<'_, '_, i32, i32>: Send, Sync, Unpin);
20 
21 impl<'ser, 'sig, B, W> Serializer<'ser, 'sig, B, W>
22 where
23     B: byteorder::ByteOrder,
24     W: Write + Seek,
25 {
26     /// Create a GVariant Serializer struct instance.
new<'w: 'ser, 'f: 'ser>( signature: &Signature<'sig>, writer: &'w mut W, fds: &'f mut Vec<RawFd>, ctxt: EncodingContext<B>, ) -> Self27     pub fn new<'w: 'ser, 'f: 'ser>(
28         signature: &Signature<'sig>,
29         writer: &'w mut W,
30         fds: &'f mut Vec<RawFd>,
31         ctxt: EncodingContext<B>,
32     ) -> Self {
33         assert_eq!(ctxt.format(), EncodingFormat::GVariant);
34 
35         let sig_parser = SignatureParser::new(signature.clone());
36         Self(crate::SerializerCommon {
37             ctxt,
38             sig_parser,
39             writer,
40             fds,
41             bytes_written: 0,
42             value_sign: None,
43             b: PhantomData,
44         })
45     }
46 
serialize_maybe<T>(&mut self, value: Option<&T>) -> Result<()> where T: ?Sized + Serialize,47     fn serialize_maybe<T>(&mut self, value: Option<&T>) -> Result<()>
48     where
49         T: ?Sized + Serialize,
50     {
51         let signature = self.0.sig_parser.next_signature()?;
52         let alignment = alignment_for_signature(&signature, self.0.ctxt.format());
53         let child_sig_parser = self.0.sig_parser.slice(1..);
54         let child_signature = child_sig_parser.next_signature()?;
55         let child_sig_len = child_signature.len();
56         let fixed_sized_child = crate::utils::is_fixed_sized_signature(&child_signature)?;
57 
58         self.0.sig_parser.skip_char()?;
59 
60         self.0.add_padding(alignment)?;
61 
62         match value {
63             Some(value) => {
64                 value.serialize(&mut *self)?;
65 
66                 if !fixed_sized_child {
67                     self.0.write_all(&b"\0"[..]).map_err(Error::Io)?;
68                 }
69             }
70             None => {
71                 self.0.sig_parser.skip_chars(child_sig_len)?;
72             }
73         }
74 
75         Ok(())
76     }
77 }
78 
79 macro_rules! serialize_basic {
80     ($method:ident, $type:ty) => {
81         #[inline]
82         fn $method(self, v: $type) -> Result<()> {
83             let ctxt = EncodingContext::new_dbus(self.0.ctxt.position());
84             let bytes_written = self.0.bytes_written;
85             let mut fds = vec![];
86             let mut dbus_ser = crate::dbus::Serializer(crate::SerializerCommon::<B, W> {
87                 ctxt,
88                 sig_parser: self.0.sig_parser.clone(),
89                 writer: &mut self.0.writer,
90                 fds: &mut fds,
91                 bytes_written,
92                 value_sign: None,
93                 b: PhantomData,
94             });
95 
96             dbus_ser.$method(v)?;
97 
98             self.0.bytes_written = dbus_ser.0.bytes_written;
99             self.0.sig_parser = dbus_ser.0.sig_parser;
100             self.0.fds.extend(fds.iter());
101 
102             Ok(())
103         }
104     };
105 }
106 
107 impl<'ser, 'sig, 'b, B, W> ser::Serializer for &'b mut Serializer<'ser, 'sig, B, W>
108 where
109     B: byteorder::ByteOrder,
110     W: Write + Seek,
111 {
112     type Ok = ();
113     type Error = Error;
114 
115     type SerializeSeq = SeqSerializer<'ser, 'sig, 'b, B, W>;
116     type SerializeTuple = StructSerializer<'ser, 'sig, 'b, B, W>;
117     type SerializeTupleStruct = StructSerializer<'ser, 'sig, 'b, B, W>;
118     type SerializeTupleVariant = StructSerializer<'ser, 'sig, 'b, B, W>;
119     type SerializeMap = SeqSerializer<'ser, 'sig, 'b, B, W>;
120     type SerializeStruct = StructSerializer<'ser, 'sig, 'b, B, W>;
121     type SerializeStructVariant = StructSerializer<'ser, 'sig, 'b, B, W>;
122 
123     serialize_basic!(serialize_bool, bool);
124     serialize_basic!(serialize_i16, i16);
125     serialize_basic!(serialize_i32, i32);
126     serialize_basic!(serialize_i64, i64);
127 
128     serialize_basic!(serialize_u8, u8);
129     serialize_basic!(serialize_u16, u16);
130     serialize_basic!(serialize_u32, u32);
131     serialize_basic!(serialize_u64, u64);
132 
133     serialize_basic!(serialize_f64, f64);
134 
serialize_i8(self, v: i8) -> Result<()>135     fn serialize_i8(self, v: i8) -> Result<()> {
136         // No i8 type in GVariant, let's pretend it's i16
137         self.serialize_i16(v as i16)
138     }
139 
serialize_f32(self, v: f32) -> Result<()>140     fn serialize_f32(self, v: f32) -> Result<()> {
141         // No f32 type in GVariant, let's pretend it's f64
142         self.serialize_f64(v as f64)
143     }
144 
serialize_char(self, v: char) -> Result<()>145     fn serialize_char(self, v: char) -> Result<()> {
146         // No char type in GVariant, let's pretend it's a string
147         self.serialize_str(&v.to_string())
148     }
149 
serialize_str(self, v: &str) -> Result<()>150     fn serialize_str(self, v: &str) -> Result<()> {
151         if v.contains('\0') {
152             return Err(serde::de::Error::invalid_value(
153                 serde::de::Unexpected::Char('\0'),
154                 &"GVariant string type must not contain interior null bytes",
155             ));
156         }
157 
158         let c = self.0.sig_parser.next_char();
159         if c == VARIANT_SIGNATURE_CHAR {
160             self.0.value_sign = Some(signature_string!(v));
161 
162             // signature is serialized after the value in GVariant
163             return Ok(());
164         }
165 
166         // Strings in GVariant format require no alignment.
167 
168         self.0.sig_parser.skip_char()?;
169         self.0.write_all(v.as_bytes()).map_err(Error::Io)?;
170         self.0.write_all(&b"\0"[..]).map_err(Error::Io)?;
171 
172         Ok(())
173     }
174 
serialize_bytes(self, v: &[u8]) -> Result<()>175     fn serialize_bytes(self, v: &[u8]) -> Result<()> {
176         let seq = self.serialize_seq(Some(v.len()))?;
177         seq.ser.0.write(v).map_err(Error::Io)?;
178         seq.end()
179     }
180 
serialize_none(self) -> Result<()>181     fn serialize_none(self) -> Result<()> {
182         self.serialize_maybe::<()>(None)
183     }
184 
serialize_some<T>(self, value: &T) -> Result<()> where T: ?Sized + Serialize,185     fn serialize_some<T>(self, value: &T) -> Result<()>
186     where
187         T: ?Sized + Serialize,
188     {
189         self.serialize_maybe(Some(value))
190     }
191 
serialize_unit(self) -> Result<()>192     fn serialize_unit(self) -> Result<()> {
193         self.0.write_all(&b"\0"[..]).map_err(Error::Io)
194     }
195 
serialize_unit_struct(self, _name: &'static str) -> Result<()>196     fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
197         self.serialize_unit()
198     }
199 
serialize_unit_variant( self, _name: &'static str, variant_index: u32, _variant: &'static str, ) -> Result<()>200     fn serialize_unit_variant(
201         self,
202         _name: &'static str,
203         variant_index: u32,
204         _variant: &'static str,
205     ) -> Result<()> {
206         variant_index.serialize(self)
207     }
208 
serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()> where T: ?Sized + Serialize,209     fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
210     where
211         T: ?Sized + Serialize,
212     {
213         value.serialize(self)?;
214 
215         Ok(())
216     }
217 
serialize_newtype_variant<T>( self, _name: &'static str, variant_index: u32, _variant: &'static str, value: &T, ) -> Result<()> where T: ?Sized + Serialize,218     fn serialize_newtype_variant<T>(
219         self,
220         _name: &'static str,
221         variant_index: u32,
222         _variant: &'static str,
223         value: &T,
224     ) -> Result<()>
225     where
226         T: ?Sized + Serialize,
227     {
228         self.0.prep_serialize_enum_variant(variant_index)?;
229 
230         value.serialize(self)
231     }
232 
serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq>233     fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
234         self.0.sig_parser.skip_char()?;
235         let element_signature = self.0.sig_parser.next_signature()?;
236         let element_signature_len = element_signature.len();
237         let element_alignment = alignment_for_signature(&element_signature, self.0.ctxt.format());
238 
239         let fixed_sized_child = crate::utils::is_fixed_sized_signature(&element_signature)?;
240         let offsets = if !fixed_sized_child {
241             Some(FramingOffsets::new())
242         } else {
243             None
244         };
245 
246         let key_start = if self.0.sig_parser.next_char() == DICT_ENTRY_SIG_START_CHAR {
247             let key_signature = Signature::from_str_unchecked(&element_signature[1..2]);
248             if !crate::utils::is_fixed_sized_signature(&key_signature)? {
249                 Some(0)
250             } else {
251                 None
252             }
253         } else {
254             None
255         };
256         self.0.add_padding(element_alignment)?;
257 
258         let start = self.0.bytes_written;
259 
260         Ok(SeqSerializer {
261             ser: self,
262             start,
263             element_alignment,
264             element_signature_len,
265             offsets,
266             key_start,
267         })
268     }
269 
serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple>270     fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
271         self.serialize_struct("", len)
272     }
273 
serialize_tuple_struct( self, name: &'static str, len: usize, ) -> Result<Self::SerializeTupleStruct>274     fn serialize_tuple_struct(
275         self,
276         name: &'static str,
277         len: usize,
278     ) -> Result<Self::SerializeTupleStruct> {
279         self.serialize_struct(name, len)
280     }
281 
serialize_tuple_variant( self, name: &'static str, variant_index: u32, _variant: &'static str, len: usize, ) -> Result<Self::SerializeTupleVariant>282     fn serialize_tuple_variant(
283         self,
284         name: &'static str,
285         variant_index: u32,
286         _variant: &'static str,
287         len: usize,
288     ) -> Result<Self::SerializeTupleVariant> {
289         self.0.prep_serialize_enum_variant(variant_index)?;
290 
291         self.serialize_struct(name, len)
292     }
293 
serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap>294     fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
295         self.serialize_seq(len)
296     }
297 
serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct>298     fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
299         let c = self.0.sig_parser.next_char();
300         let end_parens;
301         if c == VARIANT_SIGNATURE_CHAR {
302             self.0.add_padding(VARIANT_ALIGNMENT_GVARIANT)?;
303             end_parens = false;
304         } else {
305             let signature = self.0.sig_parser.next_signature()?;
306             let alignment = alignment_for_signature(&signature, EncodingFormat::GVariant);
307             self.0.add_padding(alignment)?;
308 
309             self.0.sig_parser.skip_char()?;
310 
311             if c == STRUCT_SIG_START_CHAR || c == DICT_ENTRY_SIG_START_CHAR {
312                 end_parens = true;
313             } else {
314                 let expected = format!(
315                     "`{}` or `{}`",
316                     STRUCT_SIG_START_STR, DICT_ENTRY_SIG_START_STR,
317                 );
318                 return Err(serde::de::Error::invalid_type(
319                     serde::de::Unexpected::Char(c),
320                     &expected.as_str(),
321                 ));
322             }
323         }
324 
325         let offsets = if c == STRUCT_SIG_START_CHAR {
326             Some(FramingOffsets::new())
327         } else {
328             None
329         };
330         let start = self.0.bytes_written;
331 
332         Ok(StructSerializer {
333             ser: self,
334             start,
335             end_parens,
336             offsets,
337         })
338     }
339 
serialize_struct_variant( self, name: &'static str, variant_index: u32, _variant: &'static str, len: usize, ) -> Result<Self::SerializeStructVariant>340     fn serialize_struct_variant(
341         self,
342         name: &'static str,
343         variant_index: u32,
344         _variant: &'static str,
345         len: usize,
346     ) -> Result<Self::SerializeStructVariant> {
347         self.0.prep_serialize_enum_variant(variant_index)?;
348 
349         self.serialize_struct(name, len)
350     }
351 }
352 
353 #[doc(hidden)]
354 pub struct SeqSerializer<'ser, 'sig, 'b, B, W> {
355     ser: &'b mut Serializer<'ser, 'sig, B, W>,
356     start: usize,
357     // alignment of element
358     element_alignment: usize,
359     // size of element signature
360     element_signature_len: usize,
361     // All offsets
362     offsets: Option<FramingOffsets>,
363     // start of last dict-entry key written
364     key_start: Option<usize>,
365 }
366 
367 impl<'ser, 'sig, 'b, B, W> SeqSerializer<'ser, 'sig, 'b, B, W>
368 where
369     B: byteorder::ByteOrder,
370     W: Write + Seek,
371 {
end_seq(self) -> Result<()>372     pub(self) fn end_seq(self) -> Result<()> {
373         self.ser
374             .0
375             .sig_parser
376             .skip_chars(self.element_signature_len)?;
377 
378         let offsets = match self.offsets {
379             Some(offsets) => offsets,
380             None => return Ok(()),
381         };
382         let array_len = self.ser.0.bytes_written - self.start;
383         if array_len == 0 {
384             // Empty sequence
385             assert!(offsets.is_empty());
386 
387             return Ok(());
388         }
389 
390         offsets.write_all(&mut self.ser.0, array_len)?;
391 
392         Ok(())
393     }
394 }
395 
396 impl<'ser, 'sig, 'b, B, W> ser::SerializeSeq for SeqSerializer<'ser, 'sig, 'b, B, W>
397 where
398     B: byteorder::ByteOrder,
399     W: Write + Seek,
400 {
401     type Ok = ();
402     type Error = Error;
403 
serialize_element<T>(&mut self, value: &T) -> Result<()> where T: ?Sized + Serialize,404     fn serialize_element<T>(&mut self, value: &T) -> Result<()>
405     where
406         T: ?Sized + Serialize,
407     {
408         // We want to keep parsing the same signature repeatedly for each element so we use a
409         // disposable clone.
410         let sig_parser = self.ser.0.sig_parser.clone();
411         self.ser.0.sig_parser = sig_parser.clone();
412 
413         value.serialize(&mut *self.ser)?;
414         self.ser.0.sig_parser = sig_parser;
415 
416         if let Some(ref mut offsets) = self.offsets {
417             let offset = self.ser.0.bytes_written - self.start;
418 
419             offsets.push(offset);
420         }
421 
422         Ok(())
423     }
424 
end(self) -> Result<()>425     fn end(self) -> Result<()> {
426         self.end_seq()
427     }
428 }
429 
430 #[doc(hidden)]
431 pub struct StructSerializer<'ser, 'sig, 'b, B, W> {
432     ser: &'b mut Serializer<'ser, 'sig, B, W>,
433     start: usize,
434     end_parens: bool,
435     // All offsets
436     offsets: Option<FramingOffsets>,
437 }
438 
439 impl<'ser, 'sig, 'b, B, W> StructSerializer<'ser, 'sig, 'b, B, W>
440 where
441     B: byteorder::ByteOrder,
442     W: Write + Seek,
443 {
serialize_struct_element<T>(&mut self, name: Option<&'static str>, value: &T) -> Result<()> where T: ?Sized + Serialize,444     fn serialize_struct_element<T>(&mut self, name: Option<&'static str>, value: &T) -> Result<()>
445     where
446         T: ?Sized + Serialize,
447     {
448         match name {
449             Some("zvariant::Value::Value") => {
450                 // Serializing the value of a Value, which means signature was serialized
451                 // already, and also put aside for us to be picked here.
452                 let signature = self
453                     .ser
454                     .0
455                     .value_sign
456                     .take()
457                     .expect("Incorrect Value encoding");
458 
459                 let sig_parser = SignatureParser::new(signature.clone());
460                 let bytes_written = self.ser.0.bytes_written;
461                 let mut fds = vec![];
462                 let mut ser = Serializer(crate::SerializerCommon::<B, W> {
463                     ctxt: self.ser.0.ctxt,
464                     sig_parser,
465                     writer: self.ser.0.writer,
466                     fds: &mut fds,
467                     bytes_written,
468                     value_sign: None,
469                     b: PhantomData,
470                 });
471                 value.serialize(&mut ser)?;
472                 self.ser.0.bytes_written = ser.0.bytes_written;
473                 self.ser.0.fds.extend(fds.iter());
474 
475                 self.ser.0.write_all(&b"\0"[..]).map_err(Error::Io)?;
476                 self.ser
477                     .0
478                     .write_all(signature.as_bytes())
479                     .map_err(Error::Io)?;
480 
481                 Ok(())
482             }
483             _ => {
484                 let element_signature = self.ser.0.sig_parser.next_signature()?;
485                 let fixed_sized_element =
486                     crate::utils::is_fixed_sized_signature(&element_signature)?;
487 
488                 value.serialize(&mut *self.ser)?;
489 
490                 if let Some(ref mut offsets) = self.offsets {
491                     if !fixed_sized_element {
492                         offsets.push_front(self.ser.0.bytes_written - self.start);
493                     }
494                 }
495 
496                 Ok(())
497             }
498         }
499     }
500 
end_struct(self) -> Result<()>501     fn end_struct(self) -> Result<()> {
502         if self.end_parens {
503             self.ser.0.sig_parser.skip_char()?;
504         }
505         let mut offsets = match self.offsets {
506             Some(offsets) => offsets,
507             None => return Ok(()),
508         };
509         let struct_len = self.ser.0.bytes_written - self.start;
510         if struct_len == 0 {
511             // Empty sequence
512             assert!(offsets.is_empty());
513 
514             return Ok(());
515         }
516         if offsets.peek() == Some(struct_len) {
517             // For structs, we don't want offset of last element
518             offsets.pop();
519         }
520 
521         offsets.write_all(&mut self.ser.0, struct_len)?;
522 
523         Ok(())
524     }
525 }
526 
527 macro_rules! serialize_struct_anon_fields {
528     ($trait:ident $method:ident) => {
529         impl<'ser, 'sig, 'b, B, W> ser::$trait for StructSerializer<'ser, 'sig, 'b, B, W>
530         where
531             B: byteorder::ByteOrder,
532             W: Write + Seek,
533         {
534             type Ok = ();
535             type Error = Error;
536 
537             fn $method<T>(&mut self, value: &T) -> Result<()>
538             where
539                 T: ?Sized + Serialize,
540             {
541                 self.serialize_struct_element(None, value)
542             }
543 
544             fn end(self) -> Result<()> {
545                 self.end_struct()
546             }
547         }
548     };
549 }
550 serialize_struct_anon_fields!(SerializeTuple serialize_element);
551 serialize_struct_anon_fields!(SerializeTupleStruct serialize_field);
552 serialize_struct_anon_fields!(SerializeTupleVariant serialize_field);
553 
554 impl<'ser, 'sig, 'b, B, W> ser::SerializeMap for SeqSerializer<'ser, 'sig, 'b, B, W>
555 where
556     B: byteorder::ByteOrder,
557     W: Write + Seek,
558 {
559     type Ok = ();
560     type Error = Error;
561 
serialize_key<T>(&mut self, key: &T) -> Result<()> where T: ?Sized + Serialize,562     fn serialize_key<T>(&mut self, key: &T) -> Result<()>
563     where
564         T: ?Sized + Serialize,
565     {
566         self.ser.0.add_padding(self.element_alignment)?;
567 
568         if self.key_start.is_some() {
569             self.key_start.replace(self.ser.0.bytes_written);
570         }
571 
572         // We want to keep parsing the same signature repeatedly for each key so we use a
573         // disposable clone.
574         let sig_parser = self.ser.0.sig_parser.clone();
575         self.ser.0.sig_parser = sig_parser.clone();
576 
577         // skip `{`
578         self.ser.0.sig_parser.skip_char()?;
579 
580         key.serialize(&mut *self.ser)?;
581         self.ser.0.sig_parser = sig_parser;
582 
583         Ok(())
584     }
585 
serialize_value<T>(&mut self, value: &T) -> Result<()> where T: ?Sized + Serialize,586     fn serialize_value<T>(&mut self, value: &T) -> Result<()>
587     where
588         T: ?Sized + Serialize,
589     {
590         // For non-fixed-sized keys, we must add the key offset after the value
591         let key_offset = self.key_start.map(|start| self.ser.0.bytes_written - start);
592 
593         // We want to keep parsing the same signature repeatedly for each key so we use a
594         // disposable clone.
595         let sig_parser = self.ser.0.sig_parser.clone();
596         self.ser.0.sig_parser = sig_parser.clone();
597 
598         // skip `{` and key char
599         self.ser.0.sig_parser.skip_chars(2)?;
600 
601         value.serialize(&mut *self.ser)?;
602         // Restore the original parser
603         self.ser.0.sig_parser = sig_parser;
604 
605         if let Some(key_offset) = key_offset {
606             let entry_size = self.ser.0.bytes_written - self.key_start.unwrap_or(0);
607             let offset_size = FramingOffsetSize::for_encoded_container(entry_size);
608             offset_size.write_offset(&mut self.ser.0, key_offset)?;
609         }
610 
611         // And now the offset of the array element end (which is encoded later)
612         if let Some(ref mut offsets) = self.offsets {
613             let offset = self.ser.0.bytes_written - self.start;
614 
615             offsets.push(offset);
616         }
617 
618         Ok(())
619     }
620 
end(self) -> Result<()>621     fn end(self) -> Result<()> {
622         self.end_seq()
623     }
624 }
625 
626 macro_rules! serialize_struct_named_fields {
627     ($trait:ident) => {
628         impl<'ser, 'sig, 'b, B, W> ser::$trait for StructSerializer<'ser, 'sig, 'b, B, W>
629         where
630             B: byteorder::ByteOrder,
631             W: Write + Seek,
632         {
633             type Ok = ();
634             type Error = Error;
635 
636             fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
637             where
638                 T: ?Sized + Serialize,
639             {
640                 self.serialize_struct_element(Some(key), value)
641             }
642 
643             fn end(self) -> Result<()> {
644                 self.end_struct()
645             }
646         }
647     };
648 }
649 serialize_struct_named_fields!(SerializeStruct);
650 serialize_struct_named_fields!(SerializeStructVariant);
651