1use crate::amf3::custom_encoder::CustomDecoder;
2use crate::amf3::type_marker::TypeMarker;
3use nom::Parser;
4
5use crate::PADDING;
6use crate::amf3::length::Length;
7use crate::nom_utils::AMFResult;
8use crate::types::*;
9use crate::types::{Element, Value};
10use enumset::EnumSet;
11use nom::Err;
12use nom::bytes::complete::{tag, take};
13use nom::combinator::{map, map_res};
14use nom::error::{ErrorKind, make_error};
15use nom::lib::std::collections::HashMap;
16use nom::multi::{many_m_n, separated_list0};
17use nom::number::complete::{be_f64, be_i32, be_u8, be_u32};
18
19use std::convert::{TryFrom, TryInto};
20use std::rc::Rc;
21
22const REFERENCE_FLAG: u32 = 0x01;
23
24#[cfg(fuzzing)]
25pub fn fuzz_read_int_signed(i: &[u8]) -> AMFResult<'_, i32> {
27 read_int_signed(i)
28}
29
30#[allow(clippy::unusual_byte_groupings)]
31fn read_int_signed(i: &[u8]) -> AMFResult<'_, i32> {
32 let (mut i, num) = be_u8(i)?;
34 let mut value = (num & 0b01111111) as i32;
35 if num & 0b10000000 == 0 {
37 return Ok((i, value));
38 }
39
40 for _ in 0..2 {
41 let (j, num) = be_u8(i)?;
42 i = j;
43 value = (value << 7) | ((num & 0b01111111) as i32);
44 if num & 0b10000000 == 0 {
46 return Ok((i, value));
47 }
48 }
49 let (i, num) = be_u8(i)?;
50 value = (value << 8) | (num as i32);
51
52 if value & 0b000_1000000_0000000_0000000_00000000 != 0 {
54 value -= 0b001_0000000_0000000_0000000_00000000;
55 }
56
57 Ok((i, value))
58}
59
60#[cfg(fuzzing)]
61pub fn fuzz_read_int(i: &[u8]) -> AMFResult<'_, u32> {
63 read_int(i)
64}
65
66#[allow(clippy::unusual_byte_groupings)]
67fn read_int(i: &[u8]) -> AMFResult<'_, u32> {
68 let (mut i, num) = be_u8(i)?;
70 let mut value = (num & 0b01111111) as u32;
71 if num & 0b10000000 == 0 {
73 return Ok((i, value));
74 }
75
76 for _ in 0..2 {
77 let (j, num) = be_u8(i)?;
78 i = j;
79 value = (value << 7) | ((num & 0b01111111) as u32);
80 if num & 0b10000000 == 0 {
82 return Ok((i, value));
83 }
84 }
85 let (i, num) = be_u8(i)?;
86 value = (value << 8) | (num as u32);
87
88 if value & 0b000_1000000_0000000_0000000_00000000 != 0 {
89 value <<= 1;
90 value += 1;
91 }
92
93 Ok((i, value))
94}
95
96#[cfg(test)]
97mod read_number_tests {
98 use crate::amf3::read::{read_int, read_int_signed};
99
100 #[test]
101 fn test_read_1byte_number() {
102 assert_eq!(
103 0b00101011,
104 read_int_signed(&[0b00101011]).expect("Test fail").1
105 )
106 }
107
108 #[test]
109 fn test_read_4byte_number() {
110 let i = &[0b10000000, 0b11000000, 0b10000000, 0b10000000];
111 assert_eq!(2097280, read_int_signed(i).expect("Test fail").1);
112 }
113
114 #[test]
115 fn read_neg_number() {
116 assert_eq!(
117 -268435455,
118 read_int_signed(&[192, 128, 128, 1]).expect("Test fail").1
119 );
120 }
121
122 #[test]
123 fn test_read_1byte_number_unsigned() {
124 assert_eq!(0b00101011, read_int(&[0b00101011]).expect("Test fail").1)
125 }
126
127 #[test]
128 fn test_read_4byte_number_unsigned() {
129 let i = &[0b10000000, 0b11000000, 0b10000000, 0b10000000];
130 assert_eq!(2097280, read_int(i).expect("Test fail").1);
131 }
132
133 #[test]
134 fn read_neg_number_unsigned() {
135 assert_eq!(
136 536870915,
137 read_int(&[192, 128, 128, 1]).expect("Test fail").1
138 );
139 }
140}
141
142fn read_length(i: &[u8]) -> AMFResult<'_, Length> {
143 let (i, val) = read_int(i)?;
144 Ok((
145 i,
146 match val & REFERENCE_FLAG == 0 {
147 true => Length::Reference(val as usize >> 1),
148 false => Length::Size(val >> 1),
149 },
150 ))
151}
152
153fn parse_element_int(i: &[u8]) -> AMFResult<'_, Value> {
154 let (i, s) = map(read_int_signed, Value::Integer).parse(i)?;
155 Ok((i, (s)))
156}
157
158#[derive(Default)]
160pub struct AMF3Decoder {
161 pub string_reference_table: Vec<Vec<u8>>,
163
164 pub trait_reference_table: Vec<ClassDefinition>,
166
167 external_decoders: HashMap<String, Rc<dyn CustomDecoder>>,
169
170 object_id: i64,
173}
174
175fn parse_element_number(i: &[u8]) -> AMFResult<'_, Value> {
176 let (i, v) = map(be_f64, Value::Number).parse(i)?;
177 Ok((i, v))
178}
179
180impl AMF3Decoder {
181 pub fn register_custom_decoder<T: CustomDecoder + Default + 'static>(&mut self, name: &str) {
183 self.external_decoders
184 .insert(name.to_string(), Rc::new(T::default()));
185 }
186
187 fn parse_element_string<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Value> {
188 let (i, s) = map(|i| self.parse_string(i), Value::String).parse(i)?;
189 Ok((i, (s)))
190 }
191
192 #[cfg(fuzzing)]
193 pub fn fuzz_parse_string<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, String> {
195 self.parse_string(i)
196 }
197
198 fn parse_string<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, String> {
199 let (i, bytes) = self.parse_byte_stream(i)?;
200 let bytes_str =
201 String::from_utf8(bytes).map_err(|_| Err::Error(make_error(i, ErrorKind::Alpha)))?;
202 Ok((i, bytes_str))
203 }
204
205 fn parse_class_def<'a>(&mut self, length: u32, i: &'a [u8]) -> AMFResult<'a, ClassDefinition> {
206 if length & REFERENCE_FLAG == 0 {
207 let len_usize: usize = (length >> 1)
208 .try_into()
209 .map_err(|_| Err::Error(make_error(i, ErrorKind::Digit)))?;
210
211 let class_def = self
212 .trait_reference_table
213 .get(len_usize)
214 .ok_or_else(|| Err::Error(make_error(i, ErrorKind::Digit)))?
215 .clone();
216
217 return Ok((i, class_def));
218 }
219 let length = length >> 1;
220
221 let (i, name) = self.parse_byte_stream(i)?;
223 let name_str = if name.is_empty() {
224 "".to_string()
225 } else {
226 String::from_utf8(name).map_err(|_| Err::Error(make_error(i, ErrorKind::Alpha)))?
227 };
228
229 let encoding = (length & 0x03) as u8;
230
231 let attributes_count = length >> 2;
232
233 let attr_count_usize: usize = attributes_count
234 .try_into()
235 .map_err(|_| Err::Error(make_error(i, ErrorKind::Digit)))?;
236
237 let (i, static_props) =
239 many_m_n(attr_count_usize, attr_count_usize, |i| self.parse_string(i)).parse(i)?;
240
241 let is_external = encoding & 0b1 == 1;
242 let is_dynamic = encoding & 0b10 == 0b10;
243
244 let mut attributes = EnumSet::empty();
245
246 if is_external {
247 attributes |= Attribute::External;
248 }
249 if is_dynamic {
250 attributes |= Attribute::Dynamic;
251 }
252
253 let class_def = ClassDefinition {
254 name: name_str,
255 attributes,
256 static_properties: static_props,
257 };
258
259 self.trait_reference_table.push(class_def.clone());
260 Ok((i, class_def))
261 }
262
263 fn parse_reference_or_val<'a>(
264 &mut self,
265 i: &'a [u8],
266 parser: impl FnOnce(&mut Self, &'a [u8], usize, ObjectId) -> AMFResult<'a, Value>,
267 ) -> AMFResult<'a, Value> {
268 let (i, len) = read_length(i)?;
269
270 match len {
271 Length::Reference(index) => Ok((i, Value::Amf3ObjectReference(ObjectId(index as _)))),
272 Length::Size(len) => {
273 let len_usize: usize = len
274 .try_into()
275 .map_err(|_| Err::Error(make_error(i, ErrorKind::Digit)))?;
276
277 let index = self.object_id;
278 self.object_id += 1;
279
280 let (i, res) = parser(self, i, len_usize, ObjectId(index))?;
281
282 Ok((i, res))
283 }
284 }
285 }
286
287 fn parse_byte_stream<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Vec<u8>> {
288 let (i, len) = read_length(i)?;
289
290 match len {
291 Length::Size(len) => {
292 if len == 0 {
293 Ok((i, Vec::new()))
294 } else {
295 let (i, bytes) = take(len)(i)?;
296 self.string_reference_table.push(bytes.to_vec());
297 Ok((i, bytes.to_vec()))
298 }
299 }
300 Length::Reference(index) => {
301 let ref_result = self
302 .string_reference_table
303 .get(index)
304 .ok_or_else(|| Err::Error(make_error(i, ErrorKind::Digit)))?
305 .clone();
306
307 Ok((i, ref_result))
308 }
309 }
310 }
311
312 fn parse_object_static<'a>(
313 &mut self,
314 i: &'a [u8],
315 class_def: &ClassDefinition,
316 ) -> AMFResult<'a, Vec<Element>> {
317 let mut elements = Vec::new();
318 let mut i = i;
319
320 for name in class_def.static_properties.iter() {
321 let (j, e) = self.parse_single_element(i)?;
322
323 elements.push(Element {
324 name: name.clone(),
325 value: e,
326 });
327
328 i = j;
329 }
330
331 Ok((i, elements))
332 }
333
334 pub(crate) fn parse_element_object<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Value> {
335 let (i, mut length) = read_int(i)?;
336
337 if length & REFERENCE_FLAG == 0 {
338 let len_usize: usize = (length >> 1)
339 .try_into()
340 .map_err(|_| Err::Error(make_error(i, ErrorKind::Digit)))?;
341 return Ok((i, Value::Amf3ObjectReference(ObjectId(len_usize as _))));
342 }
343 length >>= 1;
344
345 let mut obj = Value::Object {
346 id: ObjectId(self.object_id),
347 data: ObjectValue {
348 elements: Vec::new(),
349 class_definition: None,
350 },
351 };
352 self.object_id += 1;
353
354 let (i, class_def) = self.parse_class_def(length, i)?;
356
357 if let Value::Object { id: _, data } = &mut obj {
358 data.class_definition = Some(class_def.clone());
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 let dec = self.external_decoders.get(&class_def.name).map(Rc::clone);
367 return if let Some(decoder) = dec {
368 let (j, v) = decoder.decode(i, self)?;
369 external_elements = v;
370 i = j;
371 let value = Value::Custom(CustomObjectValue {
373 elements: external_elements,
374 dynamic_elements: Vec::new(),
375 class_definition: class_def.clone(),
376 });
377
378 Ok((i, value))
379 } else {
380 Err(Err::Error(make_error(i, ErrorKind::Tag)))
381 };
382 }
383
384 if class_def.attributes.contains(Attribute::Dynamic) {
385 let (j, x) = self.parse_object_static(i, &class_def)?;
386 elements.extend(x);
387
388 let (mut j, mut attr) = self.parse_byte_stream(j)?;
390 while !attr.is_empty() {
391 let attr_str = String::from_utf8(attr)
392 .map_err(|_| Err::Error(make_error(i, ErrorKind::Alpha)))?;
393 let (k, val) = self.parse_single_element(j)?;
394 elements.push(Element {
395 name: attr_str,
396 value: val,
397 });
398
399 let (k, attr2) = self.parse_byte_stream(k)?;
400 j = k;
401 attr = attr2;
402 }
403 i = j;
404 }
405 if class_def.attributes.is_empty() {
406 let (j, x) = self.parse_object_static(i, &class_def)?;
407 elements.extend(x);
408
409 i = j;
410 }
411
412 if let Value::Object { id: _, data } = &mut obj {
413 data.elements = elements;
414 }
415
416 Ok((i, obj))
417 }
418
419 fn parse_element_byte_array<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Value> {
420 self.parse_reference_or_val(i, |_this, i, len, _| {
421 let (i, bytes) = take(len)(i)?;
422 Ok((i, Value::ByteArray(bytes.to_vec())))
423 })
424 }
425
426 fn parse_element_vector_int<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Value> {
427 self.parse_reference_or_val(i, |_this, i, len, _| {
428 if i.len() < len * 4 {
430 return Err(Err::Error(make_error(i, ErrorKind::TooLarge)));
431 }
432
433 let (i, fixed_length) = be_u8(i)?;
434
435 let (i, values) = many_m_n(len, len, be_i32).parse(i)?;
436
437 Ok((
438 i,
439 Value::VectorInt(VectorPrimitiveValue {
440 values,
441 fixed_length: fixed_length == 1,
442 }),
443 ))
444 })
445 }
446
447 fn parse_element_vector_uint<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Value> {
448 self.parse_reference_or_val(i, |_this, i, len, _| {
449 if i.len() < len * 4 {
451 return Err(Err::Error(make_error(i, ErrorKind::TooLarge)));
452 }
453 let (i, fixed_length) = be_u8(i)?;
454
455 let (i, values) = many_m_n(len, len, be_u32).parse(i)?;
456
457 Ok((
458 i,
459 Value::VectorUInt(VectorPrimitiveValue {
460 values,
461 fixed_length: fixed_length == 1,
462 }),
463 ))
464 })
465 }
466
467 fn parse_element_vector_double<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Value> {
468 self.parse_reference_or_val(i, |_this, i, len, _| {
469 if i.len() < len * 8 {
471 return Err(Err::Error(make_error(i, ErrorKind::TooLarge)));
472 }
473 let (i, fixed_length) = be_u8(i)?;
474
475 let (i, values) = many_m_n(len, len, be_f64).parse(i)?;
476
477 Ok((
478 i,
479 Value::VectorDouble(VectorPrimitiveValue {
480 values,
481 fixed_length: fixed_length == 1,
482 }),
483 ))
484 })
485 }
486
487 fn parse_element_object_vector<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Value> {
488 self.parse_reference_or_val(i, |this, i, len, id| {
489 let (i, fixed_length) = be_u8(i)?;
490
491 let (i, object_type_name) = this.parse_string(i)?;
492
493 let (i, elems) = many_m_n(len, len, |i| this.parse_single_element(i)).parse(i)?;
494
495 Ok((
496 i,
497 Value::VectorObject {
498 id,
499 data: VectorObjectValue {
500 values: elems,
501 object_type_name,
502 fixed_length: fixed_length == 1,
503 },
504 },
505 ))
506 })
507 }
508
509 fn parse_element_array<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Value> {
510 self.parse_reference_or_val(i, |this, i, length_usize, id| {
511 if i.len() < length_usize {
513 return Err(Err::Error(make_error(i, ErrorKind::TooLarge)));
514 }
515
516 let (i, mut key) = this.parse_byte_stream(i)?;
517
518 if key.is_empty() {
519 let (i, values) =
520 many_m_n(length_usize, length_usize, |i| this.parse_single_element(i))
521 .parse(i)?;
522
523 return Ok((i, Value::StrictArray { id, values }));
524 }
525
526 let mut elements = Vec::with_capacity(length_usize);
527
528 let mut i = i;
529 while !key.is_empty() {
530 let (j, e) = this.parse_single_element(i)?;
531 let key_str = String::from_utf8(key)
532 .map_err(|_| Err::Error(make_error(i, ErrorKind::Alpha)))?;
533
534 elements.push(Element {
535 name: key_str,
536 value: e,
537 });
538 let (j, k) = this.parse_byte_stream(j)?;
539 i = j;
540 key = k;
541 }
542
543 let (i, el) =
545 many_m_n(length_usize, length_usize, |i| this.parse_single_element(i)).parse(i)?;
546
547 let elements_len = elements.len() as u32;
548
549 Ok((
550 i,
551 Value::ECMAArray {
552 id,
553 data: ECMAArrayObjectValue {
554 dense: el,
555 elements,
556 length: elements_len,
557 },
558 },
559 ))
560 })
561 }
562
563 fn parse_element_dict<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Value> {
564 self.parse_reference_or_val(i, |this, i, len, id| {
565 let (i, weak_keys) = be_u8(i)?;
567
568 if i.len() < len * 2 {
570 return Err(Err::Error(make_error(i, ErrorKind::TooLarge)));
571 }
572
573 let (i, pairs) =
574 many_m_n(len * 2, len * 2, |i| this.parse_single_element(i)).parse(i)?;
575
576 let pairs = pairs
577 .as_chunks::<2>()
578 .0
579 .iter()
580 .map(|[key, value]| DictionaryEntry {
581 key: key.clone(),
582 value: value.clone(),
583 })
584 .collect::<Vec<_>>();
585
586 Ok((
587 i,
588 Value::Dictionary {
589 id,
590 data: DictionaryObjectValue {
591 weak_keys: weak_keys == 1,
592 elements: pairs,
593 },
594 },
595 ))
596 })
597 }
598
599 fn parse_element_date<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Value> {
600 self.parse_reference_or_val(i, |_this, i, _len, _| {
601 let (i, time) = be_f64(i)?;
602 Ok((
603 i,
604 Value::Date {
605 time,
606 timezone_or_utc: None,
607 },
608 ))
609 })
610 }
611
612 fn parse_element_xml<'a>(&mut self, i: &'a [u8], string: bool) -> AMFResult<'a, Value> {
613 self.parse_reference_or_val(i, |_this, i, len, _| {
614 let (i, data) = map_res(take(len as u32), std::str::from_utf8).parse(i)?;
615 Ok((
616 i,
617 Value::XML {
618 value: data.to_string(),
619 is_string: string,
620 },
621 ))
622 })
623 }
624
625 fn read_type_marker<'a>(&self, i: &'a [u8]) -> AMFResult<'a, TypeMarker> {
626 let (i, type_) = be_u8(i)?;
627 if let Ok(type_) = TypeMarker::try_from(type_) {
628 Ok((i, type_))
629 } else {
630 Err(Err::Error(crate::errors::Error::UnsupportedType(type_)))
631 }
632 }
633
634 pub fn parse_single_element<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Value> {
636 let (i, type_) = self.read_type_marker(i)?;
637
638 match type_ {
639 TypeMarker::Undefined => Ok((i, (Value::Undefined))),
640 TypeMarker::Null => Ok((i, (Value::Null))),
641 TypeMarker::False => Ok((i, (Value::Bool(false)))),
642 TypeMarker::True => Ok((i, (Value::Bool(true)))),
643 TypeMarker::Integer => parse_element_int(i),
644 TypeMarker::Number => parse_element_number(i),
645 TypeMarker::String => self.parse_element_string(i),
646 TypeMarker::Xml => self.parse_element_xml(i, false),
647 TypeMarker::Date => self.parse_element_date(i),
648 TypeMarker::Array => self.parse_element_array(i),
649 TypeMarker::Object => self.parse_element_object(i),
650 TypeMarker::XmlString => self.parse_element_xml(i, true),
651 TypeMarker::ByteArray => self.parse_element_byte_array(i),
652 TypeMarker::VectorObject => self.parse_element_object_vector(i),
653 TypeMarker::VectorInt => self.parse_element_vector_int(i),
654 TypeMarker::VectorUInt => self.parse_element_vector_uint(i),
655 TypeMarker::VectorDouble => self.parse_element_vector_double(i),
656 TypeMarker::Dictionary => self.parse_element_dict(i),
657 }
658 }
659
660 fn parse_element<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Element> {
661 let (i, name) = self.parse_string(i)?;
662
663 map(
664 |i| self.parse_single_element(i),
665 move |v| Element {
666 name: name.clone(),
667 value: v,
668 },
669 )
670 .parse(i)
671 }
672
673 pub fn parse_body<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Vec<Element>> {
675 let (i, elements) =
676 separated_list0(tag(PADDING.as_slice()), |i| self.parse_element(i)).parse(i)?;
677 let (i, _) = tag(PADDING.as_slice())(i)?;
678 Ok((i, elements))
679 }
680}