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}