tl_types/
deserialize.rs

1use std::fmt;
2
3#[derive(Clone, Debug, PartialEq)]
4pub enum Error {
5    /// The end of the buffer was reached earlier than anticipated, which
6    /// implies there is not enough data to complete the deserialization.
7    UnexpectedEof,
8
9    /// The error type indicating an unexpected constructor was found,
10    /// for example, when reading data that doesn't represent the
11    /// correct type (e.g. reading a `bool` when we expect a `Vec`).
12    /// In particular, it can occur in the following situations:
13    ///
14    /// * When reading a boolean.
15    /// * When reading a boxed vector.
16    /// * When reading an arbitrary boxed type.
17    ///
18    /// It is important to note that unboxed or bare [`types`] lack the
19    /// constructor information, and as such they cannot be validated.
20    ///
21    /// [`types`]: types/index.html
22    UnexpectedConstructor {
23        /// The unexpected constructor identifier.
24        id: u32,
25    },
26}
27
28impl std::error::Error for Error {}
29
30impl fmt::Display for Error {
31    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32        match *self {
33            Self::UnexpectedEof => write!(f, "unexpected eof"),
34            Self::UnexpectedConstructor { id } => write!(f, "unexpected constructor: {:08x}", id),
35        }
36    }
37}
38
39/// Re-implement `Cursor` to only work over in-memory buffers and greatly
40/// narrow the possible error cases.
41pub struct Cursor<'a> {
42    buf: &'a [u8],
43    pos: usize,
44}
45
46impl<'a> Cursor<'a> {
47    pub fn from_slice(buf: &'a [u8]) -> Self {
48        Self { buf, pos: 0 }
49    }
50
51    // TODO not a fan we need to expose this (and a way to create `Cursor`),
52    //      but crypto needs it because it needs to know where deserialization
53    //      of some inner data ends.
54    pub fn pos(&self) -> usize {
55        self.pos
56    }
57
58    pub fn read_byte(&mut self) -> Result<u8> {
59        if self.pos < self.buf.len() {
60            let byte = self.buf[self.pos];
61            self.pos += 1;
62            Ok(byte)
63        } else {
64            Err(Error::UnexpectedEof)
65        }
66    }
67
68    pub fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
69        if self.pos + buf.len() > self.buf.len() {
70            Err(Error::UnexpectedEof)
71        } else {
72            buf.copy_from_slice(&self.buf[self.pos..self.pos + buf.len()]);
73            self.pos += buf.len();
74            Ok(())
75        }
76    }
77
78    pub fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
79        buf.extend(&self.buf[self.pos..]);
80        let old = self.pos;
81        self.pos = self.buf.len();
82        Ok(self.pos - old)
83    }
84}
85
86/// The problem with being generic over `std::io::Read` is that it's
87/// fallible, but in practice, we're always going to serialize in-memory,
88/// so instead we just use a `[u8]` as our buffer.
89// TODO this is only public for session
90pub type Buffer<'a, 'b> = &'a mut Cursor<'b>;
91pub type Result<T> = std::result::Result<T, Error>;
92
93/// This trait allows for data serialized according to the
94/// [Binary Data Serialization] to be deserialized into concrete instances.
95///
96/// [Binary Data Serialization]: https://core.telegram.org/mtproto/serialize
97pub trait Deserializable {
98    /// Deserializes an instance of the type from a given buffer.
99    fn deserialize(buf: Buffer) -> Result<Self>
100    where
101        Self: std::marker::Sized;
102
103    /// Convenience function to deserialize an instance from a given buffer.
104    ///
105    /// # Examples
106    ///
107    /// ```
108    /// use gramme_types::Deserializable as _;
109    ///
110    /// assert_eq!(bool::from_bytes(&[0x37, 0x97, 0x79, 0xbc]).unwrap(), false);
111    /// ```
112    fn from_bytes(buf: &[u8]) -> Result<Self>
113    where
114        Self: std::marker::Sized,
115    {
116        Self::deserialize(&mut Cursor::from_slice(buf))
117    }
118}
119
120impl Deserializable for bool {
121    /// Deserializes a boolean according to the following definitions:
122    ///
123    /// * `boolFalse#bc799737 = Bool;` deserializes into `false`.
124    /// * `boolTrue#997275b5 = Bool;` deserializes into `true`.
125    ///
126    /// # Examples
127    ///
128    /// ```
129    /// use gramme_types::Deserializable;
130    ///
131    /// assert_eq!(bool::from_bytes(&[0xb5, 0x75, 0x72, 0x99]).unwrap(), true);
132    /// assert_eq!(bool::from_bytes(&[0x37, 0x97, 0x79, 0xbc]).unwrap(), false);
133    /// ```
134    #[allow(clippy::unreadable_literal)]
135    fn deserialize(buf: Buffer) -> Result<Self> {
136        let id = u32::deserialize(buf)?;
137        match id {
138            0x997275b5u32 => Ok(true),
139            0xbc799737u32 => Ok(false),
140            _ => Err(Error::UnexpectedConstructor { id }),
141        }
142    }
143}
144
145impl Deserializable for i32 {
146    /// Deserializes a 32-bit signed integer according to the following
147    /// definition:
148    ///
149    /// * `int ? = Int;`.
150    ///
151    /// # Examples
152    ///
153    /// ```
154    /// use gramme_types::Deserializable;
155    ///
156    /// assert_eq!(i32::from_bytes(&[0x00, 0x00, 0x00, 0x00]).unwrap(), 0i32);
157    /// assert_eq!(i32::from_bytes(&[0x01, 0x00, 0x00, 0x00]).unwrap(), 1i32);
158    /// assert_eq!(i32::from_bytes(&[0xff, 0xff, 0xff, 0xff]).unwrap(), -1i32);
159    /// assert_eq!(i32::from_bytes(&[0xff, 0xff, 0xff, 0x7f]).unwrap(), i32::max_value());
160    /// assert_eq!(i32::from_bytes(&[0x00, 0x00, 0x00, 0x80]).unwrap(), i32::min_value());
161    /// ```
162    fn deserialize(buf: Buffer) -> Result<Self> {
163        let mut buffer = [0u8; 4];
164        buf.read_exact(&mut buffer)?;
165        Ok(Self::from_le_bytes(buffer))
166    }
167}
168
169impl Deserializable for u32 {
170    /// Deserializes a 32-bit unsigned integer according to the following
171    /// definition:
172    ///
173    /// * `int ? = Int;`.
174    ///
175    /// # Examples
176    ///
177    /// ```
178    /// use gramme_types::Deserializable;
179    ///
180    /// assert_eq!(u32::from_bytes(&[0x00, 0x00, 0x00, 0x00]).unwrap(), 0u32);
181    /// assert_eq!(u32::from_bytes(&[0x01, 0x00, 0x00, 0x00]).unwrap(), 1u32);
182    /// assert_eq!(u32::from_bytes(&[0xff, 0xff, 0xff, 0xff]).unwrap(), u32::max_value());
183    /// assert_eq!(u32::from_bytes(&[0x00, 0x00, 0x00, 0x00]).unwrap(), u32::min_value());
184    /// ```
185    fn deserialize(buf: Buffer) -> Result<Self> {
186        let mut buffer = [0u8; 4];
187        buf.read_exact(&mut buffer)?;
188        Ok(Self::from_le_bytes(buffer))
189    }
190}
191
192impl Deserializable for i64 {
193    /// Deserializes a 64-bit signed integer according to the following
194    /// definition:
195    ///
196    /// * `long ? = Long;`.
197    ///
198    /// # Examples
199    ///
200    /// ```
201    /// use gramme_types::Deserializable;
202    ///
203    /// assert_eq!(i64::from_bytes(&[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]).unwrap(), 0i64);
204    /// assert_eq!(i64::from_bytes(&[0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]).unwrap(), 1i64);
205    /// assert_eq!(i64::from_bytes(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]).unwrap(), (-1i64));
206    /// assert_eq!(i64::from_bytes(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f]).unwrap(), i64::max_value());
207    /// assert_eq!(i64::from_bytes(&[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80]).unwrap(), i64::min_value());
208    /// ```
209    fn deserialize(buf: Buffer) -> Result<Self> {
210        let mut buffer = [0u8; 8];
211        buf.read_exact(&mut buffer)?;
212        Ok(Self::from_le_bytes(buffer))
213    }
214}
215
216impl Deserializable for [u8; 16] {
217    /// Deserializes the 128-bit integer according to the following
218    /// definition:
219    ///
220    /// * `int128 4*[ int ] = Int128;`.
221    ///
222    /// # Examples
223    ///
224    /// ```
225    /// use gramme_types::Deserializable;
226    ///
227    /// let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
228    ///
229    /// assert_eq!(<[u8; 16]>::from_bytes(&data).unwrap(), data);
230    /// ```
231    fn deserialize(buf: Buffer) -> Result<Self> {
232        let mut buffer = [0u8; 16];
233        buf.read_exact(&mut buffer)?;
234        Ok(buffer)
235    }
236}
237
238impl Deserializable for [u8; 32] {
239    /// Deserializes the 128-bit integer according to the following
240    /// definition:
241    ///
242    /// * `int256 8*[ int ] = Int256;`.
243    ///
244    /// # Examples
245    ///
246    /// ```
247    /// use gramme_types::Deserializable;
248    ///
249    /// let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
250    ///             18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32];
251    ///
252    /// assert_eq!(<[u8; 32]>::from_bytes(&data).unwrap(), data);
253    /// ```
254    fn deserialize(buf: Buffer) -> Result<Self> {
255        let mut buffer = [0u8; 32];
256        buf.read_exact(&mut buffer)?;
257        Ok(buffer)
258    }
259}
260
261impl Deserializable for f64 {
262    /// Deserializes a 64-bit floating point according to the
263    /// following definition:
264    ///
265    /// * `double ? = Double;`.
266    ///
267    /// # Examples
268    ///
269    /// ```
270    /// use std::f64;
271    /// use gramme_types::Deserializable;
272    ///
273    /// assert_eq!(f64::from_bytes(&[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]).unwrap(), 0f64);
274    /// assert_eq!(f64::from_bytes(&[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf8, 0x3f]).unwrap(), 1.5f64);
275    /// assert_eq!(f64::from_bytes(&[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf8, 0xbf]).unwrap(), -1.5f64);
276    /// assert_eq!(f64::from_bytes(&[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf0, 0x7f]).unwrap(), f64::INFINITY);
277    /// assert_eq!(f64::from_bytes(&[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf0, 0xff]).unwrap(), f64::NEG_INFINITY);
278    /// ```
279    fn deserialize(buf: Buffer) -> Result<Self> {
280        let mut buffer = [0u8; 8];
281        buf.read_exact(&mut buffer)?;
282        Ok(Self::from_le_bytes(buffer))
283    }
284}
285
286impl<T: Deserializable> Deserializable for Vec<T> {
287    /// Deserializes a vector of deserializable items according to the
288    /// following definition:
289    ///
290    /// * `vector#1cb5c415 {t:Type} # [ t ] = Vector t;`.
291    ///
292    /// # Examples
293    ///
294    /// ```
295    /// use gramme_types::Deserializable;
296    ///
297    /// assert_eq!(Vec::<i32>::from_bytes(&[0x15, 0xc4, 0xb5, 0x1c, 0x0, 0x0, 0x0, 0x0]).unwrap(), Vec::new());
298    /// assert_eq!(Vec::<i32>::from_bytes(&[0x15, 0xc4, 0xb5, 0x1c, 0x1, 0x0, 0x0, 0x0, 0x7f, 0x0, 0x0, 0x0]).unwrap(),
299    ///            vec![0x7f_i32]);
300    /// ```
301    #[allow(clippy::unreadable_literal)]
302    fn deserialize(buf: Buffer) -> Result<Self> {
303        let id = u32::deserialize(buf)?;
304        if id != 0x1cb5c415u32 {
305            return Err(Error::UnexpectedConstructor { id });
306        }
307        let len = u32::deserialize(buf)?;
308        (0..len).map(|_| T::deserialize(buf)).collect()
309    }
310}
311
312impl<T: Deserializable> Deserializable for crate::RawVec<T> {
313    /// Deserializes a vector of deserializable items according to the
314    /// following definition:
315    ///
316    /// * `vector#1cb5c415 {t:Type} # [ t ] = Vector t;`.
317    ///
318    /// # Examples
319    ///
320    /// ```
321    /// use gramme_types::{RawVec, Deserializable};
322    ///
323    /// assert_eq!(RawVec::<i32>::from_bytes(&[0x0, 0x0, 0x0, 0x0]).unwrap().0, Vec::<i32>::new());
324    /// assert_eq!(RawVec::<i32>::from_bytes(&[0x1, 0x0, 0x0, 0x0, 0x7f, 0x0, 0x0, 0x0]).unwrap().0, vec![0x7f_i32]);
325    /// ```
326    fn deserialize(buf: Buffer) -> Result<Self> {
327        let len = u32::deserialize(buf)?;
328        Ok(Self(
329            (0..len)
330                .map(|_| T::deserialize(buf))
331                .collect::<Result<Vec<T>>>()?,
332        ))
333    }
334}
335
336impl Deserializable for String {
337    /// Deserializes a UTF-8 string according to the following definition:
338    ///
339    /// * `string ? = String;`.
340    ///
341    /// # Examples
342    ///
343    /// ```
344    /// use gramme_types::Deserializable;
345    ///
346    /// fn test_string(string: &str, prefix: &[u8], suffix: &[u8]) {
347    ///    let bytes = {
348    ///        let mut tmp = prefix.to_vec();
349    ///        tmp.extend(string.as_bytes());
350    ///        tmp.extend(suffix);
351    ///        tmp
352    ///    };
353    ///    let expected = string.to_owned();
354    ///
355    ///    assert_eq!(String::from_bytes(&bytes).unwrap(), expected);
356    /// }
357    ///
358    /// test_string("", &[0x00], &[0x00, 0x00, 0x00]);
359    /// test_string("Hi", &[0x02], &[0x0]);
360    /// test_string("Hi!", &[0x03], &[]);
361    /// test_string("Hello", &[0x05], &[0x0, 0x0]);
362    /// test_string("Hello, world!", &[0xd], &[0x0, 0x0]);
363    /// test_string(
364    ///     "This is a very long string, and it has to be longer than 253 \
365    ///      characters, which are quite a few but we can make it! Although, \
366    ///      it is quite challenging. The quick brown fox jumps over the lazy \
367    ///      fox. There is still some more text we need to type. Oh, this \
368    ///      sentence made it past!",
369    ///      &[0xfe, 0x11, 0x01, 0x00],
370    ///      &[0x00, 0x00, 0x00]
371    /// );
372    /// ```
373    fn deserialize(buf: Buffer) -> Result<Self> {
374        Ok(String::from_utf8_lossy(&Vec::<u8>::deserialize(buf)?).into())
375    }
376}
377
378impl Deserializable for Vec<u8> {
379    /// Deserializes a vector of bytes as a byte-string according to the
380    /// following definition:
381    ///
382    /// * `string ? = String;`.
383    ///
384    /// # Examples
385    ///
386    /// ```
387    /// use gramme_types::{Deserializable};
388    ///
389    /// assert_eq!(Vec::<u8>::from_bytes(&[0x00, 0x00, 0x00, 0x00]).unwrap(), Vec::new());
390    /// assert_eq!(Vec::<u8>::from_bytes(&[0x01, 0x7f, 0x00, 0x00]).unwrap(), vec![0x7f_u8]);
391    /// ```
392    fn deserialize(buf: Buffer) -> Result<Self> {
393        let first_byte = buf.read_byte()?;
394        let (len, padding) = if first_byte == 254 {
395            let mut buffer = [0u8; 3];
396            buf.read_exact(&mut buffer)?;
397            let len =
398                (buffer[0] as usize) | ((buffer[1] as usize) << 8) | ((buffer[2] as usize) << 16);
399
400            (len, len % 4)
401        } else {
402            let len = first_byte as usize;
403            (len, (len + 1) % 4)
404        };
405
406        let mut result = vec![0u8; len];
407        buf.read_exact(&mut result)?;
408
409        if padding > 0 {
410            for _ in 0..(4 - padding) {
411                buf.read_byte()?;
412            }
413        }
414
415        Ok(result)
416    }
417}