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 let (mut i, num) = be_u8(i)?;
30 let mut value = (num & 0b01111111) as i32;
31 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 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 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 let (mut i, num) = be_u8(i)?;
60 let mut value = (num & 0b01111111) as u32;
61 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 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#[derive(Default)]
141pub struct AMF3Decoder {
142 pub string_reference_table: Vec<Vec<u8>>,
144 pub trait_reference_table: Vec<ClassDefinition>,
146 pub object_reference_table: Vec<Rc<Value>>,
148 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 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 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 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 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 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 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 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 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 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 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 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 let (i, weak_keys) = be_u8(i)?;
547
548 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 #[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 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}