From 0d989011fffd768116d0ca81f6c067c7e0876f36 Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister Date: Sun, 20 Jul 2014 14:49:10 +0200 Subject: [PATCH] [swfinterp] Add support for calling methods on objects --- test/swftests/PrivateCall.as | 21 +++++++++++++++++++++ youtube_dl/swfinterp.py | 31 ++++++++++++++++++++----------- 2 files changed, 41 insertions(+), 11 deletions(-) create mode 100644 test/swftests/PrivateCall.as diff --git a/test/swftests/PrivateCall.as b/test/swftests/PrivateCall.as new file mode 100644 index 000000000..f1c110a37 --- /dev/null +++ b/test/swftests/PrivateCall.as @@ -0,0 +1,21 @@ +// input: [] +// output: 9 + +package { +public class PrivateCall { + public static function main():int{ + var f:OtherClass = new OtherClass(); + return f.func(); + } +} +} + +class OtherClass { + private function pf():int { + return 9; + } + + public function func():int { + return this.pf(); + } +} diff --git a/youtube_dl/swfinterp.py b/youtube_dl/swfinterp.py index 8ccb64c9d..d043c2f99 100644 --- a/youtube_dl/swfinterp.py +++ b/youtube_dl/swfinterp.py @@ -50,6 +50,17 @@ class _AVMClass_Object(object): return '%s#%x' % (self.avm_class.name, id(self)) +class _ScopeDict(dict): + def __init__(self, avm_class): + super(_ScopeDict, self).__init__() + self.avm_class = avm_class + + def __repr__(self): + return '%s__Scope(%s)' % ( + self.avm_class.name, + super(_ScopeDict, self).__repr__()) + + class _AVMClass(object): def __init__(self, name_idx, name): self.name_idx = name_idx @@ -59,17 +70,7 @@ class _AVMClass(object): self.methods = {} self.method_pyfunctions = {} - class ScopeDict(dict): - def __init__(self, avm_class): - super(ScopeDict, self).__init__() - self.avm_class = avm_class - - def __repr__(self): - return '%s__Scope(%s)' % ( - self.avm_class.name, - super(ScopeDict, self).__repr__()) - - self.variables = ScopeDict(self) + self.variables = _ScopeDict(self) def make_object(self): return _AVMClass_Object(self) @@ -411,6 +412,14 @@ class SWFInterpreter(object): res = func(args) stack.append(res) continue + elif isinstance(obj, _ScopeDict): + if mname in obj.avm_class.method_names: + func = self.extract_function(obj.avm_class, mname) + res = func(args) + else: + res = obj[mname] + stack.append(res) + continue elif isinstance(obj, compat_str): if mname == 'split': assert len(args) == 1