core: Fix endless loop in `process_swf5_references`
This commit fixes an issue where ruffle locks up while trying to resolve an item with non-MovieClip parents.
This commit is contained in:
parent
60a3765be2
commit
9876e03ece
|
@ -82,7 +82,8 @@ impl<'gc> MovieClipReference<'gc> {
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
} else if activation.swf_version() <= 5 {
|
} else if activation.swf_version() <= 5 {
|
||||||
let display_object = Self::process_swf5_references(activation, display_object);
|
let display_object = Self::process_swf5_references(activation, display_object)?;
|
||||||
|
|
||||||
let stage_object = display_object
|
let stage_object = display_object
|
||||||
.object()
|
.object()
|
||||||
.coerce_to_object(activation)
|
.coerce_to_object(activation)
|
||||||
|
@ -105,16 +106,20 @@ impl<'gc> MovieClipReference<'gc> {
|
||||||
fn process_swf5_references(
|
fn process_swf5_references(
|
||||||
activation: &mut Activation<'_, 'gc>,
|
activation: &mut Activation<'_, 'gc>,
|
||||||
mut display_object: DisplayObject<'gc>,
|
mut display_object: DisplayObject<'gc>,
|
||||||
) -> DisplayObject<'gc> {
|
) -> Option<DisplayObject<'gc>> {
|
||||||
// In swfv5 paths resolve to the first MovieClip parent if the target isn't a movieclip
|
// In swfv5 paths resolve to the first MovieClip parent if the target isn't a movieclip
|
||||||
if activation.swf_version() <= 5 {
|
if activation.swf_version() <= 5 {
|
||||||
while display_object.as_movie_clip().is_none() {
|
while display_object.as_movie_clip().is_none() {
|
||||||
if let Some(p) = display_object.avm1_parent() {
|
if let Some(p) = display_object.avm1_parent() {
|
||||||
display_object = p;
|
display_object = p;
|
||||||
|
} else {
|
||||||
|
// Somehow we have gotten an object that has no MovieClip up the chain
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
display_object
|
|
||||||
|
Some(display_object)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve this reference to an object
|
/// Resolve this reference to an object
|
||||||
|
@ -131,7 +136,7 @@ impl<'gc> MovieClipReference<'gc> {
|
||||||
// We have to fallback to manual path-walking if the object is removed
|
// We have to fallback to manual path-walking if the object is removed
|
||||||
if !mc.read().display_object.avm1_removed() {
|
if !mc.read().display_object.avm1_removed() {
|
||||||
let display_object = mc.read().display_object;
|
let display_object = mc.read().display_object;
|
||||||
let display_object = Self::process_swf5_references(activation, display_object);
|
let display_object = Self::process_swf5_references(activation, display_object)?;
|
||||||
|
|
||||||
// Note that there is a bug here but this *is* how it works in Flash:
|
// Note that there is a bug here but this *is* how it works in Flash:
|
||||||
// If we are using the cached DisplayObject, we return it's path, which can be changed by modifying `_name`
|
// If we are using the cached DisplayObject, we return it's path, which can be changed by modifying `_name`
|
||||||
|
@ -175,7 +180,7 @@ impl<'gc> MovieClipReference<'gc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(start) = start {
|
if let Some(start) = start {
|
||||||
let display_object = Self::process_swf5_references(activation, start);
|
let display_object = Self::process_swf5_references(activation, start)?;
|
||||||
|
|
||||||
Some((
|
Some((
|
||||||
false,
|
false,
|
||||||
|
|
Loading…
Reference in New Issue