grammers_tl_types/
deserialize.rs

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