core: Handle PlaceObject tags with malformed clip actions
Some SWFs in the wild have PlaceObject tags with ending ClipActions that are 2 bytes instead of the required 4 bytes (see #2899). Swallow the error in this case so that the tag can run.
This commit is contained in:
parent
8fc37f364f
commit
47f0f980b8
|
@ -318,6 +318,7 @@ swf_tests! {
|
||||||
(bitmap_data, "avm1/bitmap_data", 1),
|
(bitmap_data, "avm1/bitmap_data", 1),
|
||||||
(bitmap_data_noise, "avm1/bitmap_data_noise", 1),
|
(bitmap_data_noise, "avm1/bitmap_data_noise", 1),
|
||||||
(array_call_method, "avm1/array_call_method", 1),
|
(array_call_method, "avm1/array_call_method", 1),
|
||||||
|
(bad_placeobject_clipaction, "avm1/bad_placeobject_clipaction", 2),
|
||||||
(bad_swf_tag_past_eof, "avm1/bad_swf_tag_past_eof", 1),
|
(bad_swf_tag_past_eof, "avm1/bad_swf_tag_past_eof", 1),
|
||||||
(sound, "avm1/sound", 1),
|
(sound, "avm1/sound", 1),
|
||||||
(action_to_integer, "avm1/action_to_integer", 1),
|
(action_to_integer, "avm1/action_to_integer", 1),
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Load
|
||||||
|
EnterFrame
|
Binary file not shown.
|
@ -2175,7 +2175,14 @@ impl<'a> Reader<'a> {
|
||||||
event_list.set(ClipEventFlag::LOAD, flags & 0b0000_0001 != 0);
|
event_list.set(ClipEventFlag::LOAD, flags & 0b0000_0001 != 0);
|
||||||
|
|
||||||
if self.version > 5 {
|
if self.version > 5 {
|
||||||
let flags = self.read_u8()?;
|
// There are SWFs in the wild with malformed final ClipActions that is only two bytes
|
||||||
|
// instead of four bytes (see #2899). Handle this gracefully to allow the tag to run.
|
||||||
|
// TODO: We may need a more general way to handle truncated tags, since this has
|
||||||
|
// occurred in a few different places.
|
||||||
|
// Allow for only two bytes in the clip action tag.
|
||||||
|
let flags = self.read_u8().unwrap_or_default();
|
||||||
|
let flags2 = self.read_u8().unwrap_or_default();
|
||||||
|
let _ = self.read_u8();
|
||||||
event_list.set(ClipEventFlag::DRAG_OVER, flags & 0b1000_0000 != 0);
|
event_list.set(ClipEventFlag::DRAG_OVER, flags & 0b1000_0000 != 0);
|
||||||
event_list.set(ClipEventFlag::ROLL_OUT, flags & 0b0100_0000 != 0);
|
event_list.set(ClipEventFlag::ROLL_OUT, flags & 0b0100_0000 != 0);
|
||||||
event_list.set(ClipEventFlag::ROLL_OVER, flags & 0b0010_0000 != 0);
|
event_list.set(ClipEventFlag::ROLL_OVER, flags & 0b0010_0000 != 0);
|
||||||
|
@ -2185,14 +2192,11 @@ impl<'a> Reader<'a> {
|
||||||
event_list.set(ClipEventFlag::INITIALIZE, flags & 0b0000_0010 != 0);
|
event_list.set(ClipEventFlag::INITIALIZE, flags & 0b0000_0010 != 0);
|
||||||
event_list.set(ClipEventFlag::DATA, flags & 0b0000_0001 != 0);
|
event_list.set(ClipEventFlag::DATA, flags & 0b0000_0001 != 0);
|
||||||
|
|
||||||
let flags = self.read_u8()?;
|
|
||||||
// Construct was only added in SWF7, but it's not version-gated;
|
// Construct was only added in SWF7, but it's not version-gated;
|
||||||
// Construct events will still fire in SWF6 in a v7+ player. (#1424)
|
// Construct events will still fire in SWF6 in a v7+ player. (#1424)
|
||||||
event_list.set(ClipEventFlag::CONSTRUCT, flags & 0b0000_0100 != 0);
|
event_list.set(ClipEventFlag::CONSTRUCT, flags2 & 0b0000_0100 != 0);
|
||||||
event_list.set(ClipEventFlag::KEY_PRESS, flags & 0b0000_0010 != 0);
|
event_list.set(ClipEventFlag::KEY_PRESS, flags2 & 0b0000_0010 != 0);
|
||||||
event_list.set(ClipEventFlag::DRAG_OUT, flags & 0b0000_0001 != 0);
|
event_list.set(ClipEventFlag::DRAG_OUT, flags2 & 0b0000_0001 != 0);
|
||||||
|
|
||||||
self.read_u8()?;
|
|
||||||
} else {
|
} else {
|
||||||
// SWF19 pp. 48-50: For SWFv5, the ClipEventFlags only had 2 bytes of flags,
|
// SWF19 pp. 48-50: For SWFv5, the ClipEventFlags only had 2 bytes of flags,
|
||||||
// with the 2nd byte reserved (all 0).
|
// with the 2nd byte reserved (all 0).
|
||||||
|
|
Loading…
Reference in New Issue