1use crate::avm2::types::*;
2use crate::error::{Error, Result};
3use crate::extensions::ReadSwfExt;
4use std::io::Read;
5
6pub struct Reader<'a> {
7 input: &'a [u8],
8}
9
10impl<'a> ReadSwfExt<'a> for Reader<'a> {
11 #[inline(always)]
12 fn as_mut_slice(&mut self) -> &mut &'a [u8] {
13 &mut self.input
14 }
15
16 #[inline(always)]
17 fn as_slice(&self) -> &'a [u8] {
18 self.input
19 }
20}
21
22impl<'a> Reader<'a> {
23 pub fn new(input: &'a [u8]) -> Self {
24 Self { input }
25 }
26
27 #[inline]
28 pub fn seek(&mut self, data: &'a [u8], relative_offset: i32) {
29 ReadSwfExt::seek(self, data, relative_offset as isize)
30 }
31
32 #[inline]
33 pub fn seek_absolute(&mut self, data: &'a [u8], pos: usize) {
34 ReadSwfExt::seek_absolute(self, data, pos)
35 }
36
37 pub fn read(&mut self) -> Result<AbcFile> {
38 let minor_version = self.read_u16()?;
39 let major_version = self.read_u16()?;
40 let constant_pool = self.read_constant_pool()?;
41
42 let len = self.read_u30()?;
43 let mut methods = Vec::with_capacity(len as usize);
44 for _ in 0..len {
45 methods.push(self.read_method()?);
46 }
47
48 let len = self.read_u30()?;
49 let metadata = self.read_metadata(len)?;
50
51 let len = self.read_u30()?;
52 let mut instances = Vec::with_capacity(len as usize);
53 for _ in 0..len {
54 instances.push(self.read_instance()?);
55 }
56
57 let mut classes = Vec::with_capacity(len as usize);
58 for _ in 0..len {
59 classes.push(self.read_class()?);
60 }
61
62 let len = self.read_u30()?;
63 let mut scripts = Vec::with_capacity(len as usize);
64 for _ in 0..len {
65 scripts.push(self.read_script()?);
66 }
67
68 let len = self.read_u30()?;
69 let mut method_bodies = Vec::with_capacity(len as usize);
70 for _ in 0..len {
71 method_bodies.push(self.read_method_body()?);
72 }
73
74 Ok(AbcFile {
75 major_version,
76 minor_version,
77
78 constant_pool,
79 methods,
80 metadata,
81 instances,
82 classes,
83 scripts,
84 method_bodies,
85 })
86 }
87
88 fn read_u30(&mut self) -> Result<u32> {
89 self.read_encoded_u32()
90 }
91
92 fn read_i24(&mut self) -> Result<i32> {
93 Ok(i32::from(self.read_u8()?)
94 | (i32::from(self.read_u8()?) << 8)
95 | (i32::from(self.read_u8()? as i8) << 16))
96 }
97
98 fn read_i32(&mut self) -> Result<i32> {
99 Ok(self.read_encoded_u32()? as i32)
100 }
101
102 fn read_string(&mut self) -> Result<Vec<u8>> {
103 let len = self.read_u30()?;
104 let mut s = Vec::with_capacity(len as usize);
106 self.read_slice(len as usize)?.read_to_end(&mut s)?;
107 Ok(s)
108 }
109
110 fn read_index<T>(&mut self) -> Result<Index<T>> {
111 use std::marker::PhantomData;
112 Ok(Index(self.read_u30()?, PhantomData))
113 }
114
115 fn read_namespace(&mut self) -> Result<Namespace> {
116 let kind = self.read_u8()?;
117 let name: Index<String> = self.read_index()?;
118 Ok(match kind {
121 0x05 => Namespace::Private(name),
122 0x08 => Namespace::Namespace(name),
123 0x16 => Namespace::Package(name),
124 0x17 => Namespace::PackageInternal(name),
125 0x18 => Namespace::Protected(name),
126 0x19 => Namespace::Explicit(name),
127 0x1a => Namespace::StaticProtected(name),
128 _ => return Err(Error::invalid_data("Invalid namespace kind")),
129 })
130 }
131
132 fn read_namespace_set(&mut self) -> Result<NamespaceSet> {
133 let len = self.read_u30()?;
134 let mut namespace_set = Vec::with_capacity(len as usize);
135 for _ in 0..len {
136 namespace_set.push(self.read_index()?);
137 }
138 Ok(namespace_set)
139 }
140
141 fn read_multiname(&mut self) -> Result<Multiname> {
142 let kind = self.read_u8()?;
143 Ok(match kind {
144 0x07 => Multiname::QName {
145 namespace: self.read_index()?,
146 name: self.read_index()?,
147 },
148 0x0d => Multiname::QNameA {
149 namespace: self.read_index()?,
150 name: self.read_index()?,
151 },
152 0x0f => Multiname::RTQName {
153 name: self.read_index()?,
154 },
155 0x10 => Multiname::RTQNameA {
156 name: self.read_index()?,
157 },
158 0x11 => Multiname::RTQNameL,
159 0x12 => Multiname::RTQNameLA,
160 0x09 => Multiname::Multiname {
161 name: self.read_index()?,
162 namespace_set: self.read_index()?,
163 },
164 0x0e => Multiname::MultinameA {
165 name: self.read_index()?,
166 namespace_set: self.read_index()?,
167 },
168 0x1b => Multiname::MultinameL {
169 namespace_set: self.read_index()?,
170 },
171 0x1c => Multiname::MultinameLA {
172 namespace_set: self.read_index()?,
173 },
174 0x1d => {
175 let base_type = self.read_index()?;
176 let count = self.read_u30()?;
177 let mut parameters = Vec::with_capacity(count as usize);
178
179 for _ in 0..count {
180 parameters.push(self.read_index()?);
181 }
182
183 Multiname::TypeName {
184 base_type,
185 parameters,
186 }
187 }
188 _ => return Err(Error::invalid_data("Invalid multiname kind")),
189 })
190 }
191
192 fn read_constant_pool(&mut self) -> Result<ConstantPool> {
193 let len = self.read_u30()?.saturating_sub(1);
194 let mut ints = Vec::with_capacity(len as usize);
195 for _ in 0..len {
196 ints.push(self.read_i32()?);
197 }
198
199 let len = self.read_u30()?.saturating_sub(1);
200 let mut uints = Vec::with_capacity(len as usize);
201 for _ in 0..len {
202 uints.push(self.read_u30()?);
203 }
204
205 let len = self.read_u30()?.saturating_sub(1);
206 let mut doubles = Vec::with_capacity(len as usize);
207 for _ in 0..len {
208 doubles.push(self.read_f64()?);
209 }
210
211 let len = self.read_u30()?.saturating_sub(1);
212 let mut strings = Vec::with_capacity(len as usize);
213 for _ in 0..len {
214 strings.push(self.read_string()?);
215 }
216
217 let len = self.read_u30()?.saturating_sub(1);
218 let mut namespaces = Vec::with_capacity(len as usize);
219 for _ in 0..len {
220 namespaces.push(self.read_namespace()?);
221 }
222
223 let len = self.read_u30()?.saturating_sub(1);
224 let mut namespace_sets = Vec::with_capacity(len as usize);
225 for _ in 0..len {
226 namespace_sets.push(self.read_namespace_set()?);
227 }
228
229 let len = self.read_u30()?.saturating_sub(1);
230 let mut multinames = Vec::with_capacity(len as usize);
231 for _ in 0..len {
232 multinames.push(self.read_multiname()?);
233 }
234
235 Ok(ConstantPool {
236 ints,
237 uints,
238 doubles,
239 strings,
240 namespaces,
241 namespace_sets,
242 multinames,
243 })
244 }
245
246 fn read_method(&mut self) -> Result<Method> {
247 let num_params = self.read_u30()?;
248 let return_type = self.read_index()?;
249 let mut params = Vec::with_capacity(num_params as usize);
250 for _ in 0..num_params {
251 params.push(MethodParam {
252 kind: self.read_index()?,
253 name: None,
254 default_value: None,
255 })
256 }
257 let name = self.read_index()?;
258 let flags = MethodFlags::from_bits_truncate(self.read_u8()?);
259
260 if flags.contains(MethodFlags::HAS_OPTIONAL) {
261 let num_optional_params = self.read_u30()? as usize;
262 if let Some(start) = params.len().checked_sub(num_optional_params) {
263 for param in &mut params[start..] {
264 param.default_value = Some(self.read_constant_value()?);
265 }
266 } else {
267 return Err(Error::invalid_data("Too many optional parameters"));
268 }
269 }
270
271 if flags.contains(MethodFlags::HAS_PARAM_NAMES) {
272 for param in &mut params {
273 param.name = Some(self.read_index()?);
274 }
275 }
276
277 Ok(Method {
278 name,
279 params,
280 return_type,
281 flags,
282 })
283 }
284
285 fn read_constant_value(&mut self) -> Result<DefaultValue> {
286 let index = self.read_u30()?;
287 Ok(match self.read_u8()? {
288 0x00 => DefaultValue::Undefined,
289 0x01 => DefaultValue::String(Index::new(index)),
290 0x03 => DefaultValue::Int(Index::new(index)),
291 0x04 => DefaultValue::Uint(Index::new(index)),
292 0x05 => DefaultValue::Private(Index::new(index)),
293 0x06 => DefaultValue::Double(Index::new(index)),
294 0x08 => DefaultValue::Namespace(Index::new(index)),
295 0x0a => DefaultValue::False,
296 0x0b => DefaultValue::True,
297 0x0c => DefaultValue::Null,
298 0x16 => DefaultValue::Package(Index::new(index)),
299 0x17 => DefaultValue::PackageInternal(Index::new(index)),
300 0x18 => DefaultValue::Protected(Index::new(index)),
301 0x19 => DefaultValue::Explicit(Index::new(index)),
302 0x1a => DefaultValue::StaticProtected(Index::new(index)),
303 _ => return Err(Error::invalid_data("Invalid default value")),
304 })
305 }
306
307 fn read_optional_value(&mut self) -> Result<Option<DefaultValue>> {
308 let index = self.read_u30()?;
309 if index == 0 {
310 Ok(None)
311 } else {
312 Ok(Some(match self.read_u8()? {
313 0x00 => DefaultValue::Undefined,
314 0x01 => DefaultValue::String(Index::new(index)),
315 0x03 => DefaultValue::Int(Index::new(index)),
316 0x04 => DefaultValue::Uint(Index::new(index)),
317 0x05 => DefaultValue::Private(Index::new(index)),
318 0x06 => DefaultValue::Double(Index::new(index)),
319 0x08 => DefaultValue::Namespace(Index::new(index)),
320 0x0a => DefaultValue::False,
321 0x0b => DefaultValue::True,
322 0x0c => DefaultValue::Null,
323 0x16 => DefaultValue::Package(Index::new(index)),
324 0x17 => DefaultValue::PackageInternal(Index::new(index)),
325 0x18 => DefaultValue::Protected(Index::new(index)),
326 0x19 => DefaultValue::Explicit(Index::new(index)),
327 0x1a => DefaultValue::StaticProtected(Index::new(index)),
328 _ => return Err(Error::invalid_data("Invalid default value")),
329 }))
330 }
331 }
332
333 fn read_metadata(&mut self, len: u32) -> Result<Vec<Metadata>> {
334 let mut metadata = Vec::with_capacity(len as usize);
335 for _ in 0..len {
336 let name = self.read_index()?;
337 let num_items = self.read_u30()?;
338 let mut key_value_data = Vec::with_capacity(num_items as usize * 2);
339
340 for _ in 0..num_items * 2 {
342 key_value_data.push(self.read_index()?);
343 }
344
345 let mut items = Vec::with_capacity(num_items as usize);
347 for i in 0..num_items {
348 items.push(MetadataItem {
349 key: key_value_data[i as usize],
350 value: key_value_data[(num_items + i) as usize],
351 })
352 }
353
354 metadata.push(Metadata { name, items });
355 }
356
357 Ok(metadata)
358 }
359
360 fn read_instance(&mut self) -> Result<Instance> {
361 let name = self.read_index()?;
362 let super_name = self.read_index()?;
363 let flags = self.read_u8()?;
364
365 let protected_namespace = if flags & 0x08 != 0 {
366 Some(self.read_index()?)
367 } else {
368 None
369 };
370
371 let num_interfaces = self.read_u30()?;
372 let mut interfaces = Vec::with_capacity(num_interfaces as usize);
373 for _ in 0..num_interfaces {
374 interfaces.push(self.read_index()?);
375 }
376
377 let init_method = self.read_index()?;
378
379 let num_traits = self.read_u30()?;
380 let mut traits = Vec::with_capacity(num_traits as usize);
381 for _ in 0..num_traits {
382 traits.push(self.read_trait()?);
383 }
384
385 Ok(Instance {
386 name,
387 super_name,
388 protected_namespace,
389 interfaces,
390 traits,
391 init_method,
392 is_sealed: flags & 0x01 != 0,
393 is_final: flags & 0x02 != 0,
394 is_interface: flags & 0x04 != 0,
395 })
396 }
397
398 fn read_class(&mut self) -> Result<Class> {
399 let init_method = self.read_index()?;
400 let num_traits = self.read_u30()?;
401 let mut traits = Vec::with_capacity(num_traits as usize);
402 for _ in 0..num_traits {
403 traits.push(self.read_trait()?);
404 }
405 Ok(Class {
406 init_method,
407 traits,
408 })
409 }
410
411 fn read_script(&mut self) -> Result<Script> {
412 let init_method = self.read_index()?;
413 let num_traits = self.read_u30()?;
414 let mut traits = Vec::with_capacity(num_traits as usize);
415 for _ in 0..num_traits {
416 traits.push(self.read_trait()?);
417 }
418 Ok(Script {
419 init_method,
420 traits,
421 })
422 }
423
424 fn read_trait(&mut self) -> Result<Trait> {
425 let name = self.read_index()?;
426 let flags = self.read_u8()?;
427 let kind = match flags & 0b1111 {
428 0 => TraitKind::Slot {
429 slot_id: self.read_u30()?,
430 type_name: self.read_index()?,
431 value: self.read_optional_value()?,
432 },
433 1 => TraitKind::Method {
434 disp_id: self.read_u30()?,
435 method: self.read_index()?,
436 },
437 2 => TraitKind::Getter {
438 disp_id: self.read_u30()?,
439 method: self.read_index()?,
440 },
441 3 => TraitKind::Setter {
442 disp_id: self.read_u30()?,
443 method: self.read_index()?,
444 },
445 4 => TraitKind::Class {
446 slot_id: self.read_u30()?,
447 class: self.read_index()?,
448 },
449 5 => TraitKind::Function {
450 slot_id: self.read_u30()?,
451 function: self.read_index()?,
452 },
453 6 => TraitKind::Const {
454 slot_id: self.read_u30()?,
455 type_name: self.read_index()?,
456 value: self.read_optional_value()?,
457 },
458 _ => return Err(Error::invalid_data("Invalid trait kind")),
459 };
460
461 let mut metadata = vec![];
462 if flags & 0b0100_0000 != 0 {
463 let num_metadata = self.read_u30()?;
464 metadata.reserve(num_metadata as usize);
465 for _ in 0..num_metadata {
466 metadata.push(self.read_index()?);
467 }
468 }
469
470 Ok(Trait {
471 name,
472 kind,
473 metadata,
474 is_final: flags & 0b0001_0000 != 0,
475 is_override: flags & 0b0010_0000 != 0,
476 })
477 }
478
479 fn read_method_body(&mut self) -> Result<MethodBody> {
480 let method = self.read_index()?;
481 let max_stack = self.read_u30()?;
482 let num_locals = self.read_u30()?;
483 let init_scope_depth = self.read_u30()?;
484 let max_scope_depth = self.read_u30()?;
485
486 let code_len = self.read_u30()?;
488 let code = self.read_slice(code_len as usize)?.to_vec();
490
491 let num_exceptions = self.read_u30()?;
492 let mut exceptions = Vec::with_capacity(num_exceptions as usize);
493 for _ in 0..num_exceptions {
494 exceptions.push(self.read_exception()?);
495 }
496
497 let num_traits = self.read_u30()?;
498 let mut traits = Vec::with_capacity(num_traits as usize);
499 for _ in 0..num_traits {
500 traits.push(self.read_trait()?);
501 }
502
503 Ok(MethodBody {
504 method,
505 max_stack,
506 num_locals,
507 init_scope_depth,
508 max_scope_depth,
509 code,
510 exceptions,
511 traits,
512 })
513 }
514
515 pub fn read_op(&mut self) -> Result<Op> {
516 use crate::avm2::opcode::OpCode;
517 use num_traits::FromPrimitive;
518
519 let byte = self.read_u8()?;
520 let opcode = match OpCode::from_u8(byte) {
521 Some(o) => o,
522 None => return Err(Error::invalid_data(format!("Unknown ABC opcode {byte:#x}"))),
523 };
524
525 let op = match opcode {
526 OpCode::Add => Op::Add,
527 OpCode::AddI => Op::AddI,
528 OpCode::ApplyType => Op::ApplyType {
529 num_types: self.read_u30()?,
530 },
531 OpCode::AsType => Op::AsType {
532 type_name: self.read_index()?,
533 },
534 OpCode::AsTypeLate => Op::AsTypeLate,
535 OpCode::BitAnd => Op::BitAnd,
536 OpCode::BitNot => Op::BitNot,
537 OpCode::BitOr => Op::BitOr,
538 OpCode::BitXor => Op::BitXor,
539 OpCode::Bkpt => Op::Bkpt,
540 OpCode::BkptLine => Op::BkptLine {
541 line_num: self.read_u30()?,
542 },
543 OpCode::Call => Op::Call {
544 num_args: self.read_u30()?,
545 },
546 OpCode::CallMethod => Op::CallMethod {
547 index: self.read_u30()?,
548 num_args: self.read_u30()?,
549 },
550 OpCode::CallProperty => Op::CallProperty {
551 index: self.read_index()?,
552 num_args: self.read_u30()?,
553 },
554 OpCode::CallPropLex => Op::CallPropLex {
555 index: self.read_index()?,
556 num_args: self.read_u30()?,
557 },
558 OpCode::CallPropVoid => Op::CallPropVoid {
559 index: self.read_index()?,
560 num_args: self.read_u30()?,
561 },
562 OpCode::CallStatic => Op::CallStatic {
563 index: self.read_index()?,
564 num_args: self.read_u30()?,
565 },
566 OpCode::CallSuper => Op::CallSuper {
567 index: self.read_index()?,
568 num_args: self.read_u30()?,
569 },
570 OpCode::CallSuperVoid => Op::CallSuperVoid {
571 index: self.read_index()?,
572 num_args: self.read_u30()?,
573 },
574 OpCode::CheckFilter => Op::CheckFilter,
575 OpCode::Coerce => Op::Coerce {
576 index: self.read_index()?,
577 },
578 OpCode::CoerceA => Op::CoerceA,
579 OpCode::CoerceB => Op::CoerceB,
580 OpCode::CoerceD => Op::CoerceD,
581 OpCode::CoerceI => Op::CoerceI,
582 OpCode::CoerceO => Op::CoerceO,
583 OpCode::CoerceS => Op::CoerceS,
584 OpCode::CoerceU => Op::CoerceU,
585 OpCode::Construct => Op::Construct {
586 num_args: self.read_u30()?,
587 },
588 OpCode::ConstructProp => Op::ConstructProp {
589 index: self.read_index()?,
590 num_args: self.read_u30()?,
591 },
592 OpCode::ConstructSuper => Op::ConstructSuper {
593 num_args: self.read_u30()?,
594 },
595 OpCode::ConvertB => Op::ConvertB,
596 OpCode::ConvertD => Op::ConvertD,
597 OpCode::ConvertI => Op::ConvertI,
598 OpCode::ConvertO => Op::ConvertO,
599 OpCode::ConvertS => Op::ConvertS,
600 OpCode::ConvertU => Op::ConvertU,
601 OpCode::Debug => {
602 let op = Op::Debug {
603 is_local_register: self.read_u8()? != 0,
604 register_name: self.read_index()?,
605 register: self.read_u8()?,
606 };
607 self.read_u30()?; op
609 }
610 OpCode::DebugFile => Op::DebugFile {
611 file_name: self.read_index()?,
612 },
613 OpCode::DebugLine => Op::DebugLine {
614 line_num: self.read_u30()?,
615 },
616 OpCode::DecLocal => Op::DecLocal {
617 index: self.read_u30()?,
618 },
619 OpCode::DecLocalI => Op::DecLocalI {
620 index: self.read_u30()?,
621 },
622 OpCode::Decrement => Op::Decrement,
623 OpCode::DecrementI => Op::DecrementI,
624 OpCode::DeleteProperty => Op::DeleteProperty {
625 index: self.read_index()?,
626 },
627 OpCode::Divide => Op::Divide,
628 OpCode::Dup => Op::Dup,
629 OpCode::Dxns => Op::Dxns {
630 index: self.read_index()?,
631 },
632 OpCode::DxnsLate => Op::DxnsLate,
633 OpCode::Equals => Op::Equals,
634 OpCode::EscXAttr => Op::EscXAttr,
635 OpCode::EscXElem => Op::EscXElem,
636 OpCode::FindDef => Op::FindDef {
637 index: self.read_index()?,
638 },
639 OpCode::FindProperty => Op::FindProperty {
640 index: self.read_index()?,
641 },
642 OpCode::FindPropStrict => Op::FindPropStrict {
643 index: self.read_index()?,
644 },
645 OpCode::GetDescendants => Op::GetDescendants {
646 index: self.read_index()?,
647 },
648 OpCode::GetGlobalScope => Op::GetGlobalScope,
649 OpCode::GetGlobalSlot => Op::GetGlobalSlot {
650 index: self.read_u30()?,
651 },
652 OpCode::GetLex => Op::GetLex {
653 index: self.read_index()?,
654 },
655 OpCode::GetLocal => Op::GetLocal {
656 index: self.read_u30()?,
657 },
658 OpCode::GetLocal0 => Op::GetLocal { index: 0 },
659 OpCode::GetLocal1 => Op::GetLocal { index: 1 },
660 OpCode::GetLocal2 => Op::GetLocal { index: 2 },
661 OpCode::GetLocal3 => Op::GetLocal { index: 3 },
662 OpCode::GetOuterScope => Op::GetOuterScope {
663 index: self.read_u30()?,
664 },
665 OpCode::GetProperty => Op::GetProperty {
666 index: self.read_index()?,
667 },
668 OpCode::GetScopeObject => Op::GetScopeObject {
669 index: self.read_u8()?,
670 },
671 OpCode::GetSlot => Op::GetSlot {
672 index: self.read_u30()?,
673 },
674 OpCode::GetSuper => Op::GetSuper {
675 index: self.read_index()?,
676 },
677 OpCode::GreaterEquals => Op::GreaterEquals,
678 OpCode::GreaterThan => Op::GreaterThan,
679 OpCode::HasNext => Op::HasNext,
680 OpCode::HasNext2 => Op::HasNext2 {
681 object_register: self.read_u30()?,
682 index_register: self.read_u30()?,
683 },
684 OpCode::IfEq => Op::IfEq {
685 offset: self.read_i24()?,
686 },
687 OpCode::IfFalse => Op::IfFalse {
688 offset: self.read_i24()?,
689 },
690 OpCode::IfGe => Op::IfGe {
691 offset: self.read_i24()?,
692 },
693 OpCode::IfGt => Op::IfGt {
694 offset: self.read_i24()?,
695 },
696 OpCode::IfLe => Op::IfLe {
697 offset: self.read_i24()?,
698 },
699 OpCode::IfLt => Op::IfLt {
700 offset: self.read_i24()?,
701 },
702 OpCode::IfNge => Op::IfNge {
703 offset: self.read_i24()?,
704 },
705 OpCode::IfNgt => Op::IfNgt {
706 offset: self.read_i24()?,
707 },
708 OpCode::IfNle => Op::IfNle {
709 offset: self.read_i24()?,
710 },
711 OpCode::IfNlt => Op::IfNlt {
712 offset: self.read_i24()?,
713 },
714 OpCode::IfNe => Op::IfNe {
715 offset: self.read_i24()?,
716 },
717 OpCode::IfStrictEq => Op::IfStrictEq {
718 offset: self.read_i24()?,
719 },
720 OpCode::IfStrictNe => Op::IfStrictNe {
721 offset: self.read_i24()?,
722 },
723 OpCode::IfTrue => Op::IfTrue {
724 offset: self.read_i24()?,
725 },
726 OpCode::In => Op::In,
727 OpCode::IncLocal => Op::IncLocal {
728 index: self.read_u30()?,
729 },
730 OpCode::IncLocalI => Op::IncLocalI {
731 index: self.read_u30()?,
732 },
733 OpCode::Increment => Op::Increment,
734 OpCode::IncrementI => Op::IncrementI,
735 OpCode::InitProperty => Op::InitProperty {
736 index: self.read_index()?,
737 },
738 OpCode::InstanceOf => Op::InstanceOf,
739 OpCode::IsType => Op::IsType {
740 index: self.read_index()?,
741 },
742 OpCode::IsTypeLate => Op::IsTypeLate,
743 OpCode::Jump => Op::Jump {
744 offset: self.read_i24()?,
745 },
746 OpCode::Kill => Op::Kill {
747 index: self.read_u30()?,
748 },
749 OpCode::Label => Op::Label,
750 OpCode::LessEquals => Op::LessEquals,
751 OpCode::LessThan => Op::LessThan,
752 OpCode::Lf32 => Op::Lf32,
753 OpCode::Lf64 => Op::Lf64,
754 OpCode::Li16 => Op::Li16,
755 OpCode::Li32 => Op::Li32,
756 OpCode::Li8 => Op::Li8,
757 OpCode::LookupSwitch => Op::LookupSwitch(Box::new(LookupSwitch {
758 default_offset: self.read_i24()?,
759 case_offsets: {
760 let num_cases = self.read_u30()? + 1;
761 let mut case_offsets = Vec::with_capacity(num_cases as usize);
762 for _ in 0..num_cases {
763 case_offsets.push(self.read_i24()?);
764 }
765 case_offsets.into()
766 },
767 })),
768 OpCode::LShift => Op::LShift,
769 OpCode::Modulo => Op::Modulo,
770 OpCode::Multiply => Op::Multiply,
771 OpCode::MultiplyI => Op::MultiplyI,
772 OpCode::Negate => Op::Negate,
773 OpCode::NegateI => Op::NegateI,
774 OpCode::NewActivation => Op::NewActivation,
775 OpCode::NewArray => Op::NewArray {
776 num_args: self.read_u30()?,
777 },
778 OpCode::NewCatch => Op::NewCatch {
779 index: self.read_index()?,
780 },
781 OpCode::NewClass => Op::NewClass {
782 index: self.read_index()?,
783 },
784 OpCode::NewFunction => Op::NewFunction {
785 index: self.read_index()?,
786 },
787 OpCode::NewObject => Op::NewObject {
788 num_args: self.read_u30()?,
789 },
790 OpCode::NextName => Op::NextName,
791 OpCode::NextValue => Op::NextValue,
792 OpCode::Nop => Op::Nop,
793 OpCode::Not => Op::Not,
794 OpCode::Pop => Op::Pop,
795 OpCode::PopScope => Op::PopScope,
796 OpCode::PushByte => Op::PushByte {
797 value: self.read_u8()?,
798 },
799 OpCode::PushDouble => Op::PushDouble {
800 value: self.read_index()?,
801 },
802 OpCode::PushFalse => Op::PushFalse,
803 OpCode::PushInt => Op::PushInt {
804 value: self.read_index()?,
805 },
806 OpCode::PushNamespace => Op::PushNamespace {
807 value: self.read_index()?,
808 },
809 OpCode::PushNaN => Op::PushNaN,
810 OpCode::PushNull => Op::PushNull,
811 OpCode::PushScope => Op::PushScope,
812 OpCode::PushShort => Op::PushShort {
813 value: self.read_u30()? as i16,
814 },
815 OpCode::PushString => Op::PushString {
816 value: self.read_index()?,
817 },
818 OpCode::PushTrue => Op::PushTrue,
819 OpCode::PushUint => Op::PushUint {
820 value: self.read_index()?,
821 },
822 OpCode::PushUndefined => Op::PushUndefined,
823 OpCode::PushWith => Op::PushWith,
824 OpCode::ReturnValue => Op::ReturnValue,
825 OpCode::ReturnVoid => Op::ReturnVoid,
826 OpCode::RShift => Op::RShift,
827 OpCode::SetLocal => Op::SetLocal {
828 index: self.read_u30()?,
829 },
830 OpCode::SetLocal0 => Op::SetLocal { index: 0 },
831 OpCode::SetLocal1 => Op::SetLocal { index: 1 },
832 OpCode::SetLocal2 => Op::SetLocal { index: 2 },
833 OpCode::SetLocal3 => Op::SetLocal { index: 3 },
834 OpCode::SetGlobalSlot => Op::SetGlobalSlot {
835 index: self.read_u30()?,
836 },
837 OpCode::SetProperty => Op::SetProperty {
838 index: self.read_index()?,
839 },
840 OpCode::SetSlot => Op::SetSlot {
841 index: self.read_u30()?,
842 },
843 OpCode::SetSuper => Op::SetSuper {
844 index: self.read_index()?,
845 },
846 OpCode::Sf32 => Op::Sf32,
847 OpCode::Sf64 => Op::Sf64,
848 OpCode::Si16 => Op::Si16,
849 OpCode::Si32 => Op::Si32,
850 OpCode::Si8 => Op::Si8,
851 OpCode::StrictEquals => Op::StrictEquals,
852 OpCode::Subtract => Op::Subtract,
853 OpCode::SubtractI => Op::SubtractI,
854 OpCode::Swap => Op::Swap,
855 OpCode::Sxi1 => Op::Sxi1,
856 OpCode::Sxi16 => Op::Sxi16,
857 OpCode::Sxi8 => Op::Sxi8,
858 OpCode::Timestamp => Op::Timestamp,
859 OpCode::Throw => Op::Throw,
860 OpCode::TypeOf => Op::TypeOf,
861 OpCode::URShift => Op::URShift,
862 };
863
864 Ok(op)
865 }
866
867 fn read_exception(&mut self) -> Result<Exception> {
868 Ok(Exception {
869 from_offset: self.read_u30()?,
870 to_offset: self.read_u30()?,
871 target_offset: self.read_u30()?,
872 type_name: self.read_index()?,
873 variable_name: self.read_index()?,
874 })
875 }
876}
877
878#[cfg(test)]
879#[allow(clippy::unusual_byte_groupings)]
880pub mod tests {
881 use super::*;
882 use crate::test_data;
883
884 pub fn read_abc_from_file(path: &str) -> Vec<u8> {
885 use crate::types::Tag;
886 let data = std::fs::read(path).unwrap();
887 let swf_buf = crate::decompress_swf(&data[..]).unwrap();
888 let swf = crate::parse_swf(&swf_buf).unwrap();
889 for tag in swf.tags {
890 if let Tag::DoAbc2(do_abc) = tag {
891 return do_abc.data.to_vec();
892 }
893 }
894 panic!("ABC tag not found in {path}");
895 }
896
897 #[test]
898 fn read_abc() {
899 for (_, abc_file, bytes) in test_data::avm2_tests() {
900 let mut reader = Reader::new(&bytes[..]);
901 let parsed = reader.read().unwrap();
902 assert_eq!(
903 parsed, abc_file,
904 "Incorrectly parsed ABC.\nRead:\n{parsed:?}\n\nExpected:\n{abc_file:?}",
905 );
906 }
907 }
908
909 #[test]
910 fn test_round_trip_default_value() {
911 use crate::avm2::write::Writer;
912
913 let orig_bytes = read_abc_from_file("tests/swfs/Avm2DefaultValue.swf");
914 let mut reader = Reader::new(&orig_bytes[..]);
915 let parsed = reader.read().unwrap();
916
917 let mut out = vec![];
918 let mut writer = Writer::new(&mut out);
919 writer.write(parsed).unwrap();
920
921 assert_eq!(
922 orig_bytes, out,
923 "Incorrectly written Avm2DefaultValue class"
924 );
925 }
926
927 #[test]
928 fn read_u30() {
929 let read = |data: &[u8]| Reader::new(data).read_u30().unwrap();
930 assert_eq!(read(&[0]), 0);
931 assert_eq!(read(&[2]), 2);
932 assert_eq!(read(&[0b1_0000001, 0b0_0000001]), 129);
933 assert_eq!(
934 read(&[0b1_0000001, 0b1_0000001, 0b0_1100111]),
935 0b1100111_0000001_0000001
936 );
937 assert_eq!(
938 read(&[
939 0b1_0000000,
940 0b1_0000000,
941 0b1_0000000,
942 0b1_0000000,
943 0b0000_1111
944 ]),
945 0b1111_0000000_0000000_0000000_0000000
946 );
947 assert_eq!(
948 read(&[
949 0b1_0000000,
950 0b1_0000000,
951 0b1_0000000,
952 0b1_0000000,
953 0b1111_1111
954 ]),
955 0b1111_0000000_0000000_0000000_0000000
956 );
957 }
958
959 #[test]
960 fn read_i24() {
961 let read = |data: &[u8]| Reader::new(data).read_i24().unwrap();
962 assert_eq!(read(&[0, 0, 0]), 0);
963 assert_eq!(read(&[2, 0, 0]), 2);
964 assert_eq!(read(&[0b1101_0001, 0b0010_1111, 0b0000_0001]), 77777);
965 assert_eq!(read(&[0b0010_1111, 0b1101_0000, 0b1111_1110]), -77777);
966 }
967
968 #[test]
969 fn read_i32() {
970 let read = |data: &[u8]| Reader::new(data).read_i32().unwrap();
971 assert_eq!(read(&[0]), 0);
972 assert_eq!(read(&[2]), 2);
973 assert_eq!(read(&[0b1_0000001, 0b0_0000001]), 129);
974 assert_eq!(
975 read(&[
976 0b1_0000001,
977 0b1_0000001,
978 0b1_0000001,
979 0b1_0000001,
980 0b0000_0100
981 ]),
982 1075855489
983 );
984
985 assert_eq!(read(&[0b0_1000000]), 64);
988 assert_eq!(read(&[0b1_0000000, 0b0_1000000]), 8192);
989 assert_eq!(read(&[0b1_0000000, 0b1_0000000, 0b0_1000000]), 1048576);
990 assert_eq!(
991 read(&[0b1_0000000, 0b1_0000000, 0b1_0000000, 0b0_1000000]),
992 134217728
993 );
994 assert_eq!(
995 read(&[
996 0b1_0000000,
997 0b1_0000000,
998 0b1_0000000,
999 0b1_0000000,
1000 0b0000_0100
1001 ]),
1002 1073741824
1003 );
1004 assert_eq!(
1005 read(&[
1006 0b1_1111111,
1007 0b1_1111111,
1008 0b1_1111111,
1009 0b1_1111111,
1010 0b0000_0111
1011 ]),
1012 2147483647
1013 );
1014
1015 assert_eq!(
1016 read(&[
1017 0b1_1000000,
1018 0b1_1111111,
1019 0b1_1111111,
1020 0b1_1111111,
1021 0b0000_1111,
1022 ]),
1023 -64
1024 );
1025 assert_eq!(
1026 read(&[
1027 0b1_0000000,
1028 0b1_1000000,
1029 0b1_1111111,
1030 0b1_1111111,
1031 0b0000_1111
1032 ]),
1033 -8192
1034 );
1035 assert_eq!(
1036 read(&[
1037 0b1_0000000,
1038 0b1_0000000,
1039 0b1_1000000,
1040 0b1_1111111,
1041 0b0000_1111
1042 ]),
1043 -1048576
1044 );
1045 assert_eq!(
1046 read(&[
1047 0b1_0000000,
1048 0b1_0000000,
1049 0b1_0000000,
1050 0b1_1000000,
1051 0b0000_1111
1052 ]),
1053 -134217728
1054 );
1055 assert_eq!(
1056 read(&[
1057 0b1_0000000,
1058 0b1_0000000,
1059 0b1_0000000,
1060 0b1_0000000,
1061 0b0000_1000
1062 ]),
1063 -2147483648
1064 );
1065
1066 assert_eq!(read(&[0b1_0000100, 0b1_0000111, 0b0_0000100,]), 66436);
1067
1068 assert_eq!(
1069 read(&[0b1_0000100, 0b1_0000111, 0b1_0000000, 0b0_1111111,]),
1070 266339204
1071 );
1072
1073 assert_eq!(
1075 read(&[
1076 0b1_0000100,
1077 0b1_0000100,
1078 0b1_0000100,
1079 0b1_0000100,
1080 0b1111_0111
1081 ]),
1082 1887502852
1083 );
1084 }
1085}