diff --git a/core/src/avm2/activation.rs b/core/src/avm2/activation.rs index f8053b71d..07897212d 100644 --- a/core/src/avm2/activation.rs +++ b/core/src/avm2/activation.rs @@ -2901,17 +2901,23 @@ impl<'a, 'gc> Activation<'a, 'gc> { let class = self .pop_stack() .as_object() - .and_then(|c| c.as_class_object()) - .ok_or("Cannot coerce a value to a type that is null, undefined, or not a class")?; + .and_then(|c| c.as_class_object()); let value = self.pop_stack(); - if value.is_of_type(self, class) { - self.push_stack(value); + if let Some(class) = class { + if value.is_of_type(self, class) { + self.push_stack(value); + } else { + self.push_stack(Value::Null); + } + Ok(FrameControl::Continue) } else { - self.push_stack(Value::Null); + return Err(Error::AvmError(type_error( + self, + "Error #1009: Cannot access a property or method of a null object reference.", + 1009, + )?)); } - - Ok(FrameControl::Continue) } fn op_instance_of(&mut self) -> Result, Error<'gc>> { diff --git a/tests/tests/swfs/avm2/astype_missing_class/Test.as b/tests/tests/swfs/avm2/astype_missing_class/Test.as new file mode 100755 index 000000000..62fc55f81 --- /dev/null +++ b/tests/tests/swfs/avm2/astype_missing_class/Test.as @@ -0,0 +1,25 @@ +package { + import flash.display.MovieClip; + public class Test { + public function Test() { + tryCast("Hello", null); + tryCast("Hello", undefined); + tryCast("Hello", Class); + tryCast(Object, null); + tryCast(Object, undefined); + tryCast(Object, Class); + tryCast(null, null); + tryCast(null, undefined); + tryCast(undefined, null); + tryCast(undefined, undefined); + } + + private function tryCast(val: *, klass: Class) { + try { + trace(val + " as " + klass + ": " + (val as klass)); + } catch(e) { + trace("Caught error from `" + val + " as " + klass + "`: " + e); + } + } + } +} \ No newline at end of file diff --git a/tests/tests/swfs/avm2/astype_missing_class/output.txt b/tests/tests/swfs/avm2/astype_missing_class/output.txt new file mode 100644 index 000000000..e633fc0b4 --- /dev/null +++ b/tests/tests/swfs/avm2/astype_missing_class/output.txt @@ -0,0 +1,10 @@ +Caught error from `Hello as null`: TypeError: Error #1009: Cannot access a property or method of a null object reference. +Caught error from `Hello as null`: TypeError: Error #1009: Cannot access a property or method of a null object reference. +Hello as [class Class]: null +Caught error from `[class Object] as null`: TypeError: Error #1009: Cannot access a property or method of a null object reference. +Caught error from `[class Object] as null`: TypeError: Error #1009: Cannot access a property or method of a null object reference. +[class Object] as [class Class]: [class Object] +Caught error from `null as null`: TypeError: Error #1009: Cannot access a property or method of a null object reference. +Caught error from `null as null`: TypeError: Error #1009: Cannot access a property or method of a null object reference. +Caught error from `undefined as null`: TypeError: Error #1009: Cannot access a property or method of a null object reference. +Caught error from `undefined as null`: TypeError: Error #1009: Cannot access a property or method of a null object reference. diff --git a/tests/tests/swfs/avm2/astype_missing_class/test.fla b/tests/tests/swfs/avm2/astype_missing_class/test.fla new file mode 100755 index 000000000..1f329613e Binary files /dev/null and b/tests/tests/swfs/avm2/astype_missing_class/test.fla differ diff --git a/tests/tests/swfs/avm2/astype_missing_class/test.swf b/tests/tests/swfs/avm2/astype_missing_class/test.swf new file mode 100755 index 000000000..44b314c6f Binary files /dev/null and b/tests/tests/swfs/avm2/astype_missing_class/test.swf differ diff --git a/tests/tests/swfs/avm2/astype_missing_class/test.toml b/tests/tests/swfs/avm2/astype_missing_class/test.toml new file mode 100644 index 000000000..dbee897f5 --- /dev/null +++ b/tests/tests/swfs/avm2/astype_missing_class/test.toml @@ -0,0 +1 @@ +num_frames = 1