From 3d8779b377828a69ac97c3446156449fcccedda9 Mon Sep 17 00:00:00 2001 From: relrelb Date: Sat, 26 Jun 2021 16:38:52 +0300 Subject: [PATCH] swf: Ignore length mismatch in `read_action` Flash continues in such case, so just warn instead of failing. --- swf/src/avm1/read.rs | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/swf/src/avm1/read.rs b/swf/src/avm1/read.rs index a8a817d52..2bc89b223 100644 --- a/swf/src/avm1/read.rs +++ b/swf/src/avm1/read.rs @@ -55,18 +55,19 @@ impl<'a> Reader<'a> { let action = self.read_op(opcode, &mut length); - let end_pos = (start.as_ptr() as usize + length) as *const u8; if let Err(e) = action { return Err(Error::avm1_parse_error_with_source(opcode, e)); } // Verify that we parsed the correct amount of data. + let end_pos = (start.as_ptr() as usize + length) as *const u8; if self.input.as_ptr() != end_pos { - self.input = &start[length.min(start.len())..]; // We incorrectly parsed this action. // Re-sync to the expected end of the action and throw an error. - return Err(Error::avm1_parse_error(opcode)); + self.input = &start[length.min(start.len())..]; + log::warn!("Length mismatch in AVM1 action: {}", OpCode::format(opcode)); } + action } @@ -431,4 +432,26 @@ pub mod tests { let action = reader.read_action().unwrap().unwrap(); assert_eq!(action, Action::Push(vec![Value::Null, Value::Undefined])); } + + #[test] + fn read_length_mismatch() { + let action_bytes = [ + OpCode::ConstantPool as u8, + 5, + 0, + 1, + 0, + b'a', + 0, + OpCode::Add as u8, + OpCode::Subtract as u8, + ]; + let mut reader = Reader::new(&action_bytes[..], 5); + + let action = reader.read_action().unwrap().unwrap(); + assert_eq!(action, Action::ConstantPool(vec!["a".into()])); + + let action = reader.read_action().unwrap().unwrap(); + assert_eq!(action, Action::Subtract); + } }