diff options
| -rw-r--r-- | test/swftests/ConstArrayAccess.as | 18 | ||||
| -rw-r--r-- | youtube_dl/swfinterp.py | 39 | 
2 files changed, 49 insertions, 8 deletions
| diff --git a/test/swftests/ConstArrayAccess.as b/test/swftests/ConstArrayAccess.as new file mode 100644 index 000000000..07dc3f460 --- /dev/null +++ b/test/swftests/ConstArrayAccess.as @@ -0,0 +1,18 @@ +// input: [] +// output: 4 + +package { +public class ConstArrayAccess { +	private static const x:int = 2; +	private static const ar:Array = ["42", "3411"]; + +    public static function main():int{ +        var c:ConstArrayAccess = new ConstArrayAccess(); +        return c.f(); +    } + +    public function f(): int { +    	return ar[1].length; +    } +} +} diff --git a/youtube_dl/swfinterp.py b/youtube_dl/swfinterp.py index e9bf178e4..6f3c3bf95 100644 --- a/youtube_dl/swfinterp.py +++ b/youtube_dl/swfinterp.py @@ -62,13 +62,14 @@ class _ScopeDict(dict):  class _AVMClass(object): -    def __init__(self, name_idx, name): +    def __init__(self, name_idx, name, static_properties=None):          self.name_idx = name_idx          self.name = name          self.method_names = {}          self.method_idxs = {}          self.methods = {}          self.method_pyfunctions = {} +        self.static_properties = static_properties if static_properties else {}          self.variables = _ScopeDict(self)          self.constants = {} @@ -151,15 +152,20 @@ def _read_byte(reader):  StringClass = _AVMClass('(no name idx)', 'String')  ByteArrayClass = _AVMClass('(no name idx)', 'ByteArray') +TimerClass = _AVMClass('(no name idx)', 'Timer') +TimerEventClass = _AVMClass('(no name idx)', 'TimerEvent', {'TIMER': 'timer'})  _builtin_classes = {      StringClass.name: StringClass,      ByteArrayClass.name: ByteArrayClass, +    TimerClass.name: TimerClass, +    TimerEventClass.name: TimerEventClass,  }  class _Undefined(object): -    def __boolean__(self): +    def __bool__(self):          return False +    __nonzero__ = __bool__      def __hash__(self):          return 0 @@ -169,7 +175,9 @@ undefined = _Undefined()  class SWFInterpreter(object):      def __init__(self, file_contents): -        self._patched_functions = {} +        self._patched_functions = { +            (TimerClass, 'addEventListener'): lambda params: undefined, +        }          code_tag = next(tag                          for tag_code, tag in _extract_tags(file_contents)                          if tag_code == 82) @@ -346,9 +354,10 @@ class SWFInterpreter(object):              u30()  # iinit              trait_count = u30()              for _c2 in range(trait_count): -                trait_methods, constants = parse_traits_info() +                trait_methods, trait_constants = parse_traits_info()                  avm_class.register_methods(trait_methods) -                assert constants is None +                if trait_constants: +                    avm_class.constants.update(trait_constants)          assert len(classes) == class_count          self._classes_by_name = dict((c.name, c) for c in classes) @@ -439,7 +448,7 @@ class SWFInterpreter(object):              registers = [avm_class.variables] + list(args) + [None] * m.local_count              stack = []              scopes = collections.deque([ -                self._classes_by_name, avm_class.variables]) +                self._classes_by_name, avm_class.constants, avm_class.variables])              while True:                  opcode = _read_byte(coder)                  if opcode == 9:  # label @@ -587,6 +596,12 @@ class SWFInterpreter(object):                  elif opcode == 72:  # returnvalue                      res = stack.pop()                      return res +                elif opcode == 73:  # constructsuper +                    # Not yet implemented, just hope it works without it +                    arg_count = u30() +                    args = list(reversed( +                        [stack.pop() for _ in range(arg_count)])) +                    obj = stack.pop()                  elif opcode == 74:  # constructproperty                      index = u30()                      arg_count = u30() @@ -667,8 +682,11 @@ class SWFInterpreter(object):                      if mname in scope:                          res = scope[mname] +                    elif mname in _builtin_classes: +                        res = _builtin_classes[mname]                      else: -                        res = avm_class.constants[mname] +                        # Assume unitialized +                        res = undefined                      stack.append(res)                  elif opcode == 97:  # setproperty                      index = u30() @@ -694,7 +712,12 @@ class SWFInterpreter(object):                          stack.append(len(obj))                      elif isinstance(pname, compat_str):  # Member access                          obj = stack.pop() -                        assert isinstance(obj, (dict, _ScopeDict)), \ +                        if isinstance(obj, _AVMClass): +                            res = obj.static_properties[pname] +                            stack.append(res) +                            continue + +                        assert isinstance(obj, (dict, _ScopeDict)),\                              'Accessing member %r on %r' % (pname, obj)                          res = obj.get(pname, undefined)                          stack.append(res) | 
