diff options
author | Philipp Hagemeister <phihag@phihag.de> | 2014-07-20 00:03:54 +0200 |
---|---|---|
committer | Philipp Hagemeister <phihag@phihag.de> | 2014-07-20 00:03:54 +0200 |
commit | e75c24e88907f329c57cf05d729dbf599349bb50 (patch) | |
tree | 9a414da9c75e08fbf948a69ebdd5084994160f77 /youtube_dl/swfinterp.py | |
parent | 0cb2056304178ae8944e84c5bc72f96102291a12 (diff) |
[swfinterp] Extend tests and fix parsing
Diffstat (limited to 'youtube_dl/swfinterp.py')
-rw-r--r-- | youtube_dl/swfinterp.py | 47 |
1 files changed, 35 insertions, 12 deletions
diff --git a/youtube_dl/swfinterp.py b/youtube_dl/swfinterp.py index 49fade364..64a518fc6 100644 --- a/youtube_dl/swfinterp.py +++ b/youtube_dl/swfinterp.py @@ -39,6 +39,16 @@ def _extract_tags(file_contents): pos += tag_len +class _AVM_Object(object): + def __init__(self, value=None, name_hint=None): + self.value = value + self.name_hint = name_hint + + def __repr__(self): + nh = '' if self.name_hint is None else (' %s' % self.name_hint) + return 'AVMObject%s(%r)' % (nh, self.value) + + class _AVMClass_Object(object): def __init__(self, avm_class): self.avm_class = avm_class @@ -92,8 +102,8 @@ def _s32(reader): def _s24(reader): bs = reader.read(3) assert len(bs) == 3 - first_byte = b'\xff' if (ord(bs[0:1]) >= 0x80) else b'\x00' - return struct.unpack('!i', first_byte + bs) + last_byte = b'\xff' if (ord(bs[2:3]) >= 0x80) else b'\x00' + return struct.unpack('<i', bs + last_byte)[0] def _read_string(reader): @@ -341,8 +351,9 @@ class SWFInterpreter(object): u30 = lambda: _u30(coder) print('Invoking %s.%s(%r)' % (avm_class.name, func_name, tuple(args))) - registers = ['(this)'] + list(args) + [None] * m.local_count + registers = [avm_class.variables] + list(args) + [None] * m.local_count stack = [] + scopes = collections.deque([avm_class.variables]) while True: opcode = _read_byte(coder) print('opcode: %r, stack(%d): %r' % (opcode, len(stack), stack)) @@ -351,6 +362,11 @@ class SWFInterpreter(object): value = stack.pop() if value: coder.seek(coder.tell() + offset) + elif opcode == 18: # iffalse + offset = s24() + value = stack.pop() + if not value: + coder.seek(coder.tell() + offset) elif opcode == 36: # pushbyte v = _read_byte(coder) stack.append(v) @@ -361,9 +377,8 @@ class SWFInterpreter(object): idx = u30() stack.append(constant_strings[idx]) elif opcode == 48: # pushscope - # We don't implement the scope register, so we'll just - # ignore the popped value new_scope = stack.pop() + scopes.append(new_scope) elif opcode == 70: # callproperty index = u30() mname = self.multinames[index] @@ -435,20 +450,28 @@ class SWFInterpreter(object): arr.append(stack.pop()) arr = arr[::-1] stack.append(arr) - elif opcode == 93: # findpropstrict - index = u30() - mname = self.multinames[index] - res = self.extract_function(avm_class, mname) - stack.append(res) elif opcode == 94: # findproperty index = u30() mname = self.multinames[index] - res = avm_class.variables.get(mname) + for s in reversed(scopes): + if mname in s: + res = s + break + else: + res = scopes[0] stack.append(res) elif opcode == 96: # getlex index = u30() mname = self.multinames[index] - res = avm_class.variables.get(mname, None) + for s in reversed(scopes): + if mname in s: + scope = s + break + else: + scope = scopes[0] + # I cannot find where static variables are initialized + # so let's just return None + res = scope.get(mname) stack.append(res) elif opcode == 97: # setproperty index = u30() |