flash_lso/amf3/
read.rs

1use crate::amf3::custom_encoder::ExternalDecoderFn;
2use crate::amf3::type_marker::TypeMarker;
3
4use crate::amf3::length::Length;
5use crate::nom_utils::AMFResult;
6use crate::types::*;
7use crate::types::{Element, Value};
8use crate::PADDING;
9use enumset::EnumSet;
10use nom::bytes::complete::tag;
11use nom::combinator::map;
12use nom::error::{make_error, ErrorKind};
13use nom::lib::std::collections::HashMap;
14use nom::multi::{many_m_n, separated_list0};
15use nom::number::complete::{be_f64, be_i32, be_u32, be_u8};
16use nom::take;
17use nom::take_str;
18use nom::Err;
19
20use std::convert::{TryFrom, TryInto};
21use std::ops::DerefMut;
22use std::rc::Rc;
23
24const REFERENCE_FLAG: u32 = 0x01;
25
26#[allow(clippy::unusual_byte_groupings)]
27fn read_int_signed(i: &[u8]) -> AMFResult<'_, i32> {
28    // Read the first byte of the number
29    let (mut i, num) = be_u8(i)?;
30    let mut value = (num & 0b01111111) as i32;
31    // Check if we have another byte
32    if num & 0b10000000 == 0 {
33        return Ok((i, value));
34    }
35
36    for _ in 0..2 {
37        let (j, num) = be_u8(i)?;
38        i = j;
39        value = (value << 7) | ((num & 0b01111111) as i32);
40        // Check if we have another byte
41        if num & 0b10000000 == 0 {
42            return Ok((i, value));
43        }
44    }
45    let (i, num) = be_u8(i)?;
46    value = (value << 8) | (num as i32);
47
48    // Negate if negative
49    if value & 0b000_1000000_0000000_0000000_00000000 != 0 {
50        value -= 0b001_0000000_0000000_0000000_00000000;
51    }
52
53    Ok((i, value))
54}
55
56#[allow(clippy::unusual_byte_groupings)]
57fn read_int(i: &[u8]) -> AMFResult<'_, u32> {
58    // Read the first byte of the number
59    let (mut i, num) = be_u8(i)?;
60    let mut value = (num & 0b01111111) as u32;
61    // Check if we have another byte
62    if num & 0b10000000 == 0 {
63        return Ok((i, value));
64    }
65
66    for _ in 0..2 {
67        let (j, num) = be_u8(i)?;
68        i = j;
69        value = (value << 7) | ((num & 0b01111111) as u32);
70        // Check if we have another byte
71        if num & 0b10000000 == 0 {
72            return Ok((i, value));
73        }
74    }
75    let (i, num) = be_u8(i)?;
76    value = (value << 8) | (num as u32);
77
78    if value & 0b000_1000000_0000000_0000000_00000000 != 0 {
79        value <<= 1;
80        value += 1;
81    }
82
83    Ok((i, value))
84}
85
86#[cfg(test)]
87mod read_number_tests {
88    use crate::amf3::read::{read_int, read_int_signed};
89
90    #[test]
91    fn test_read_1byte_number() {
92        assert_eq!(0b00101011, read_int_signed(&[0b00101011]).unwrap().1)
93    }
94
95    #[test]
96    fn test_read_4byte_number() {
97        let i = &[0b10000000, 0b11000000, 0b10000000, 0b10000000];
98        assert_eq!(2097280, read_int_signed(i).unwrap().1);
99    }
100
101    #[test]
102    fn read_neg_number() {
103        assert_eq!(-268435455, read_int_signed(&[192, 128, 128, 1]).unwrap().1);
104    }
105
106    #[test]
107    fn test_read_1byte_number_unsigned() {
108        assert_eq!(0b00101011, read_int(&[0b00101011]).unwrap().1)
109    }
110
111    #[test]
112    fn test_read_4byte_number_unsigned() {
113        let i = &[0b10000000, 0b11000000, 0b10000000, 0b10000000];
114        assert_eq!(2097280, read_int(i).unwrap().1);
115    }
116
117    #[test]
118    fn read_neg_number_unsigned() {
119        assert_eq!(536870915, read_int(&[192, 128, 128, 1]).unwrap().1);
120    }
121}
122
123fn read_length(i: &[u8]) -> AMFResult<'_, Length> {
124    let (i, val) = read_int(i)?;
125    Ok((
126        i,
127        match val & REFERENCE_FLAG == 0 {
128            true => Length::Reference(val as usize >> 1),
129            false => Length::Size(val >> 1),
130        },
131    ))
132}
133
134fn parse_element_int(i: &[u8]) -> AMFResult<'_, Rc<Value>> {
135    let (i, s) = map(read_int_signed, Value::Integer)(i)?;
136    Ok((i, Rc::new(s)))
137}
138
139/// Handles decoding AMF3
140#[derive(Default)]
141pub struct AMF3Decoder {
142    /// The table used to cache repeated byte strings
143    pub string_reference_table: Vec<Vec<u8>>,
144    /// The table used to cache repeated trait definitions
145    pub trait_reference_table: Vec<ClassDefinition>,
146    /// The table used to cache repeated objects
147    pub object_reference_table: Vec<Rc<Value>>,
148    /// Encoders used for handling externalized types
149    pub external_decoders: HashMap<String, ExternalDecoderFn>,
150}
151
152fn parse_element_number(i: &[u8]) -> AMFResult<'_, Rc<Value>> {
153    let (i, v) = map(be_f64, Value::Number)(i)?;
154    Ok((i, Rc::new(v)))
155}
156
157impl AMF3Decoder {
158    fn parse_element_string<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Rc<Value>> {
159        let (i, s) = map(|i| self.parse_string(i), Value::String)(i)?;
160        Ok((i, Rc::new(s)))
161    }
162
163    fn parse_string<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, String> {
164        let (i, bytes) = self.parse_byte_stream(i)?;
165        let bytes_str =
166            String::from_utf8(bytes).map_err(|_| Err::Error(make_error(i, ErrorKind::Alpha)))?;
167        Ok((i, bytes_str))
168    }
169
170    fn parse_class_def<'a>(&mut self, length: u32, i: &'a [u8]) -> AMFResult<'a, ClassDefinition> {
171        if length & REFERENCE_FLAG == 0 {
172            let len_usize: usize = (length >> 1)
173                .try_into()
174                .map_err(|_| Err::Error(make_error(i, ErrorKind::Digit)))?;
175
176            let class_def = self
177                .trait_reference_table
178                .get(len_usize)
179                .ok_or_else(|| Err::Error(make_error(i, ErrorKind::Digit)))?
180                .clone();
181
182            return Ok((i, class_def));
183        }
184        let length = length >> 1;
185
186        //TODO: should name be Option<String>
187        let (i, name) = self.parse_byte_stream(i)?;
188        let name_str = if name.is_empty() {
189            "".to_string()
190        } else {
191            String::from_utf8(name).map_err(|_| Err::Error(make_error(i, ErrorKind::Alpha)))?
192        };
193
194        let encoding = (length & 0x03) as u8;
195
196        let attributes_count = length >> 2;
197
198        let attr_count_usize: usize = attributes_count
199            .try_into()
200            .map_err(|_| Err::Error(make_error(i, ErrorKind::Digit)))?;
201
202        // Read static attributes if they exist
203        let (i, static_props) =
204            many_m_n(attr_count_usize, attr_count_usize, |i| self.parse_string(i))(i)?;
205
206        let is_external = encoding & 0b1 == 1;
207        let is_dynamic = encoding & 0b10 == 0b10;
208
209        let mut attributes = EnumSet::empty();
210
211        if is_external {
212            attributes |= Attribute::External;
213        }
214        if is_dynamic {
215            attributes |= Attribute::Dynamic;
216        }
217
218        let class_def = ClassDefinition {
219            name: name_str,
220            attributes,
221            static_properties: static_props,
222        };
223
224        self.trait_reference_table.push(class_def.clone());
225        Ok((i, class_def))
226    }
227
228    fn parse_reference_or_val<'a>(
229        &mut self,
230        i: &'a [u8],
231        parser: impl FnOnce(&mut Self, &'a [u8], usize) -> AMFResult<'a, Value>,
232    ) -> AMFResult<'a, Rc<Value>> {
233        let (i, len) = read_length(i)?;
234
235        match len {
236            Length::Reference(index) => {
237                let ref_result = Rc::clone(
238                    self.object_reference_table
239                        .get(index)
240                        .ok_or_else(|| Err::Error(make_error(i, ErrorKind::Digit)))?,
241                );
242
243                Ok((i, ref_result))
244            }
245            Length::Size(len) => {
246                let len_usize: usize = len
247                    .try_into()
248                    .map_err(|_| Err::Error(make_error(i, ErrorKind::Digit)))?;
249
250                let initial = Rc::new(Value::Null);
251                let index = self.object_reference_table.len();
252                self.object_reference_table.push(initial);
253
254                let (i, res) = parser(self, i, len_usize)?;
255
256                //TODO: this should be an error case and also never happen
257                let mut initial_inner = Rc::get_mut(
258                    self.object_reference_table
259                        .get_mut(index)
260                        .expect("Index not in reference table"),
261                )
262                .expect("Reference still held to rc");
263                *initial_inner.deref_mut() = res;
264
265                Ok((
266                    i,
267                    Rc::clone(
268                        self.object_reference_table
269                            .get(index)
270                            .expect("Index not in reference table"),
271                    ),
272                ))
273            }
274        }
275    }
276
277    fn parse_byte_stream<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Vec<u8>> {
278        let (i, len) = read_length(i)?;
279
280        match len {
281            Length::Size(len) => {
282                if len == 0 {
283                    Ok((i, vec![]))
284                } else {
285                    let (i, bytes) = take!(i, len)?;
286                    self.string_reference_table.push(bytes.to_vec());
287                    Ok((i, bytes.to_vec()))
288                }
289            }
290            Length::Reference(index) => {
291                let ref_result = self
292                    .string_reference_table
293                    .get(index)
294                    .ok_or_else(|| Err::Error(make_error(i, ErrorKind::Digit)))?
295                    .clone();
296
297                Ok((i, ref_result))
298            }
299        }
300    }
301
302    fn parse_object_static<'a>(
303        &mut self,
304        i: &'a [u8],
305        class_def: &ClassDefinition,
306    ) -> AMFResult<'a, Vec<Element>> {
307        let mut elements = Vec::new();
308        let mut i = i;
309
310        for name in class_def.static_properties.iter() {
311            let (j, e) = self.parse_single_element(i)?;
312
313            elements.push(Element {
314                name: name.clone(),
315                value: e,
316            });
317
318            i = j;
319        }
320
321        Ok((i, elements))
322    }
323
324    pub(crate) fn parse_element_object<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Rc<Value>> {
325        let (i, mut length) = read_int(i)?;
326
327        if length & REFERENCE_FLAG == 0 {
328            let len_usize: usize = (length >> 1)
329                .try_into()
330                .map_err(|_| Err::Error(make_error(i, ErrorKind::Digit)))?;
331
332            let obj = Rc::clone(
333                self.object_reference_table
334                    .get(len_usize)
335                    .ok_or_else(|| Err::Error(make_error(i, ErrorKind::Digit)))?,
336            );
337
338            return Ok((i, obj));
339        }
340        length >>= 1;
341
342        let obj = Rc::new(Value::Object(Vec::new(), None));
343        let index = self.object_reference_table.len();
344        self.object_reference_table.push(obj);
345
346        // Class def
347        let (i, class_def) = self.parse_class_def(length, i)?;
348
349        {
350            let mut_obj = Rc::get_mut(
351                self.object_reference_table
352                    .get_mut(index)
353                    .expect("Index invalid"),
354            )
355            .expect("Unable to get Object");
356            if let Value::Object(_, ref mut def) = mut_obj {
357                *def = Some(class_def.clone());
358            }
359        }
360
361        let mut elements = Vec::new();
362        let external_elements;
363
364        let mut i = i;
365        if class_def.attributes.contains(Attribute::External) {
366            return if self.external_decoders.contains_key(&class_def.name) {
367                let decoder = Rc::clone(&self.external_decoders[&class_def.name]);
368                let (j, v) = decoder(i, self)?;
369                external_elements = v;
370                i = j;
371                //TODO: should it be possible to have both dynamic and external together
372                Ok((
373                    i,
374                    Rc::new(Value::Custom(
375                        external_elements,
376                        vec![],
377                        Some(class_def.clone()),
378                    )),
379                ))
380            } else {
381                Err(Err::Error(make_error(i, ErrorKind::Tag)))
382            };
383        }
384
385        let mut i = i;
386        if class_def.attributes.contains(Attribute::Dynamic) {
387            let (j, x) = self.parse_object_static(i, &class_def)?;
388            elements.extend(x);
389
390            // Read dynamic
391            let (mut j, mut attr) = self.parse_byte_stream(j)?;
392            while !attr.is_empty() {
393                let attr_str = String::from_utf8(attr)
394                    .map_err(|_| Err::Error(make_error(i, ErrorKind::Alpha)))?;
395                let (k, val) = self.parse_single_element(j)?;
396                elements.push(Element {
397                    name: attr_str,
398                    value: val,
399                });
400
401                let (k, attr2) = self.parse_byte_stream(k)?;
402                j = k;
403                attr = attr2;
404            }
405            i = j;
406        }
407        if class_def.attributes.is_empty() {
408            let (j, x) = self.parse_object_static(i, &class_def)?;
409            elements.extend(x);
410
411            i = j;
412        }
413
414        {
415            let mut_obj = Rc::get_mut(
416                self.object_reference_table
417                    .get_mut(index)
418                    .expect("Index invalid"),
419            )
420            .expect("Unable to get Object");
421            if let Value::Object(ref mut elements_inner, _) = mut_obj {
422                *elements_inner = elements;
423            }
424        }
425
426        Ok((
427            i,
428            Rc::clone(
429                self.object_reference_table
430                    .get(index)
431                    .expect("Index invalid"),
432            ),
433        ))
434    }
435
436    fn parse_element_byte_array<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Rc<Value>> {
437        self.parse_reference_or_val(i, |_this, i, len| {
438            let (i, bytes) = take!(i, len)?;
439            Ok((i, Value::ByteArray(bytes.to_vec())))
440        })
441    }
442
443    fn parse_element_vector_int<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Rc<Value>> {
444        self.parse_reference_or_val(i, |_this, i, len| {
445            // There must be at least `len * 4` (i32 = 4 bytes) bytes to read this, this prevents OOM errors with v.large vecs
446            if i.len() < len * 4 {
447                return Err(Err::Error(make_error(i, ErrorKind::TooLarge)));
448            }
449
450            let (i, fixed_length) = be_u8(i)?;
451
452            let (i, ints) = many_m_n(len, len, be_i32)(i)?;
453
454            Ok((i, Value::VectorInt(ints, fixed_length == 1)))
455        })
456    }
457
458    fn parse_element_vector_uint<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Rc<Value>> {
459        self.parse_reference_or_val(i, |_this, i, len| {
460            // There must be at least `len * 4` (u32 = 4 bytes) bytes to read this, this prevents OOM errors with v.large vecs
461            if i.len() < len * 4 {
462                return Err(Err::Error(make_error(i, ErrorKind::TooLarge)));
463            }
464            let (i, fixed_length) = be_u8(i)?;
465
466            let (i, ints) = many_m_n(len, len, be_u32)(i)?;
467
468            Ok((i, Value::VectorUInt(ints, fixed_length == 1)))
469        })
470    }
471
472    fn parse_element_vector_double<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Rc<Value>> {
473        self.parse_reference_or_val(i, |_this, i, len| {
474            // There must be at least `len * 8` (f64 = 8 bytes) bytes to read this, this prevents OOM errors with v.large dicts
475            if i.len() < len * 8 {
476                return Err(Err::Error(make_error(i, ErrorKind::TooLarge)));
477            }
478            let (i, fixed_length) = be_u8(i)?;
479
480            let (i, numbers) = many_m_n(len, len, be_f64)(i)?;
481
482            Ok((i, Value::VectorDouble(numbers, fixed_length == 1)))
483        })
484    }
485
486    fn parse_element_object_vector<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Rc<Value>> {
487        self.parse_reference_or_val(i, |this, i, len| {
488            let (i, fixed_length) = be_u8(i)?;
489
490            let (i, object_type_name) = this.parse_string(i)?;
491
492            let (i, elems) = many_m_n(len, len, |i| this.parse_single_element(i))(i)?;
493
494            Ok((
495                i,
496                Value::VectorObject(elems, object_type_name, fixed_length == 1),
497            ))
498        })
499    }
500
501    fn parse_element_array<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Rc<Value>> {
502        self.parse_reference_or_val(i, |this, i, length_usize| {
503            // There must be at least `length_usize` bytes to read this, this prevents OOM errors with v.large dicts
504            if i.len() < length_usize {
505                return Err(Err::Error(make_error(i, ErrorKind::TooLarge)));
506            }
507
508            let (i, mut key) = this.parse_byte_stream(i)?;
509
510            if key.is_empty() {
511                let (i, elements) =
512                    many_m_n(length_usize, length_usize, |i| this.parse_single_element(i))(i)?;
513
514                return Ok((i, Value::StrictArray(elements)));
515            }
516
517            let mut elements = Vec::with_capacity(length_usize);
518
519            let mut i = i;
520            while !key.is_empty() {
521                let (j, e) = this.parse_single_element(i)?;
522                let key_str = String::from_utf8(key)
523                    .map_err(|_| Err::Error(make_error(i, ErrorKind::Alpha)))?;
524
525                elements.push(Element {
526                    name: key_str,
527                    value: e,
528                });
529                let (j, k) = this.parse_byte_stream(j)?;
530                i = j;
531                key = k;
532            }
533
534            // Must parse `length` elements
535            let (i, el) =
536                many_m_n(length_usize, length_usize, |i| this.parse_single_element(i))(i)?;
537
538            let elements_len = elements.len() as u32;
539            Ok((i, Value::ECMAArray(el, elements, elements_len)))
540        })
541    }
542
543    fn parse_element_dict<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Rc<Value>> {
544        self.parse_reference_or_val(i, |this, i, len| {
545            //TODO: implications of this
546            let (i, weak_keys) = be_u8(i)?;
547
548            // There must be at least `len * 2` bytes (due to (key,val) pairs) to read this, this prevents OOM errors with v.large dicts
549            if i.len() < len * 2 {
550                return Err(Err::Error(make_error(i, ErrorKind::TooLarge)));
551            }
552
553            let (i, pairs) = many_m_n(len * 2, len * 2, |i| this.parse_single_element(i))(i)?;
554
555            let pairs = pairs
556                .chunks_exact(2)
557                .map(|chunk| (chunk[0].clone(), chunk[1].clone()))
558                .collect::<Vec<_>>();
559
560            Ok((i, Value::Dictionary(pairs, weak_keys == 1)))
561        })
562    }
563
564    fn parse_element_date<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Rc<Value>> {
565        self.parse_reference_or_val(i, |_this, i, _len| {
566            let (i, ms) = be_f64(i)?;
567            Ok((i, Value::Date(ms, None)))
568        })
569    }
570
571    fn parse_element_xml<'a>(&mut self, i: &'a [u8], string: bool) -> AMFResult<'a, Rc<Value>> {
572        self.parse_reference_or_val(i, |_this, i, len| {
573            let (i, data) = take_str!(i, len as u32)?;
574            Ok((i, Value::XML(data.into(), string)))
575        })
576    }
577
578    fn read_type_marker<'a>(&self, i: &'a [u8]) -> AMFResult<'a, TypeMarker> {
579        let (i, type_) = be_u8(i)?;
580        if let Ok(type_) = TypeMarker::try_from(type_) {
581            Ok((i, type_))
582        } else {
583            Err(Err::Error(make_error(i, ErrorKind::HexDigit)))
584        }
585    }
586
587    /// Parse a single AMF3 element from the input
588    #[inline]
589    pub fn parse_single_element<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Rc<Value>> {
590        let (i, type_) = self.read_type_marker(i)?;
591
592        match type_ {
593            TypeMarker::Undefined => Ok((i, Rc::new(Value::Undefined))),
594            TypeMarker::Null => Ok((i, Rc::new(Value::Null))),
595            TypeMarker::False => Ok((i, Rc::new(Value::Bool(false)))),
596            TypeMarker::True => Ok((i, Rc::new(Value::Bool(true)))),
597            TypeMarker::Integer => parse_element_int(i),
598            TypeMarker::Number => parse_element_number(i),
599            TypeMarker::String => self.parse_element_string(i),
600            TypeMarker::XML => self.parse_element_xml(i, false),
601            TypeMarker::Date => self.parse_element_date(i),
602            TypeMarker::Array => self.parse_element_array(i),
603            TypeMarker::Object => self.parse_element_object(i),
604            TypeMarker::XmlString => self.parse_element_xml(i, true),
605            TypeMarker::ByteArray => self.parse_element_byte_array(i),
606            TypeMarker::VectorObject => self.parse_element_object_vector(i),
607            TypeMarker::VectorInt => self.parse_element_vector_int(i),
608            TypeMarker::VectorUInt => self.parse_element_vector_uint(i),
609            TypeMarker::VectorDouble => self.parse_element_vector_double(i),
610            TypeMarker::Dictionary => self.parse_element_dict(i),
611        }
612    }
613
614    fn parse_element<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Element> {
615        let (i, name) = self.parse_string(i)?;
616
617        map(
618            |i| self.parse_single_element(i),
619            move |v| Element {
620                name: name.clone(),
621                value: v,
622            },
623        )(i)
624    }
625
626    /// Parse an AMF3 body from a slice into a list of elements
627    pub fn parse_body<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Vec<Element>> {
628        let (i, elements) = separated_list0(tag(PADDING), |i| self.parse_element(i))(i)?;
629        let (i, _) = tag(PADDING)(i)?;
630        Ok((i, elements))
631    }
632}