diff options
| -rw-r--r-- | youtube_dl/swfinterp.py | 46 | 
1 files changed, 40 insertions, 6 deletions
| diff --git a/youtube_dl/swfinterp.py b/youtube_dl/swfinterp.py index f4ee022f4..008cd76c7 100644 --- a/youtube_dl/swfinterp.py +++ b/youtube_dl/swfinterp.py @@ -151,6 +151,16 @@ def _read_byte(reader):  StringClass = _AVMClass('(no name idx)', 'String') +class _Undefined(object): +    def __boolean__(self): +        return False + +    def __hash__(self): +        return 0 + +undefined = _Undefined() + +  class SWFInterpreter(object):      def __init__(self, file_contents):          self._patched_functions = {} @@ -423,6 +433,8 @@ class SWFInterpreter(object):                          coder.seek(coder.tell() + offset)                  elif opcode == 32:  # pushnull                      stack.append(None) +                elif opcode == 33:  # pushundefined +                    stack.append(undefined)                  elif opcode == 36:  # pushbyte                      v = _read_byte(coder)                      stack.append(v) @@ -430,6 +442,8 @@ class SWFInterpreter(object):                      stack.append(True)                  elif opcode == 39:  # pushfalse                      stack.append(False) +                elif opcode == 40:  # pushnan +                    stack.append(float('NaN'))                  elif opcode == 42:  # dup                      value = stack[-1]                      stack.append(value) @@ -493,8 +507,12 @@ class SWFInterpreter(object):                      elif obj == StringClass:                          if mname == 'String':                              assert len(args) == 1 -                            assert isinstance(args[0], (int, compat_str)) -                            res = compat_str(args[0]) +                            assert isinstance(args[0], ( +                                int, compat_str, _Undefined)) +                            if args[0] == undefined: +                                res = 'undefined' +                            else: +                                res = compat_str(args[0])                              stack.append(res)                              continue                          else: @@ -505,7 +523,7 @@ class SWFInterpreter(object):                          'Unsupported property %r on %r'                          % (mname, obj))                  elif opcode == 71:  # returnvoid -                    res = None +                    res = undefined                      return res                  elif opcode == 72:  # returnvalue                      res = stack.pop() @@ -533,13 +551,13 @@ class SWFInterpreter(object):                      if isinstance(obj, _AVMClass_Object):                          func = self.extract_function(obj.avm_class, mname)                          res = func(args) -                        assert res is None +                        assert res is undefined                          continue                      if isinstance(obj, _ScopeDict):                          assert mname in obj.avm_class.method_names                          func = self.extract_function(obj.avm_class, mname)                          res = func(args) -                        assert res is None +                        assert res is undefined                          continue                      if mname == 'reverse':                          assert isinstance(obj, list) @@ -617,7 +635,7 @@ class SWFInterpreter(object):                          obj = stack.pop()                          assert isinstance(obj, (dict, _ScopeDict)), \                              'Accessing member %r on %r' % (pname, obj) -                        res = obj.get(pname, None) +                        res = obj.get(pname, undefined)                          stack.append(res)                      else:  # Assume attribute access                          idx = stack.pop() @@ -631,8 +649,24 @@ class SWFInterpreter(object):                      stack.append(intvalue)                  elif opcode == 128:  # coerce                      u30() +                elif opcode == 130:  # coerce_a +                    value = stack.pop() +                    # um, yes, it's any value +                    stack.append(value)                  elif opcode == 133:  # coerce_s                      assert isinstance(stack[-1], (type(None), compat_str)) +                elif opcode == 147:  # decrement +                    value = stack.pop() +                    assert isinstance(value, int) +                    stack.append(value - 1) +                elif opcode == 149:  # typeof +                    value = stack.pop() +                    return { +                        _Undefined: 'undefined', +                        compat_str: 'String', +                        int: 'Number', +                        float: 'Number', +                    }[type(value)]                  elif opcode == 160:  # add                      value2 = stack.pop()                      value1 = stack.pop() | 
