mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-10-31 06:35:12 +00:00 
			
		
		
		
	[swfinterp] Extend tests and fix parsing
This commit is contained in:
		
							
								
								
									
										13
									
								
								test/swftests/StaticAssignment.as
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								test/swftests/StaticAssignment.as
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| // input: [1] | ||||
| // output: 1 | ||||
|  | ||||
| package { | ||||
| public class StaticAssignment { | ||||
| 	public static var v:int; | ||||
|  | ||||
|     public static function main(a:int):int{ | ||||
|         v = a; | ||||
|         return v; | ||||
|     } | ||||
| } | ||||
| } | ||||
							
								
								
									
										16
									
								
								test/swftests/StaticRetrieval.as
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								test/swftests/StaticRetrieval.as
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| // input: [] | ||||
| // output: 1 | ||||
|  | ||||
| package { | ||||
| public class StaticRetrieval { | ||||
| 	public static var v:int; | ||||
|  | ||||
|     public static function main():int{ | ||||
|         if (v) { | ||||
|         	return 0; | ||||
|         } else { | ||||
|         	return 1; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -23,10 +23,10 @@ class TestSWFInterpreter(unittest.TestCase): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| for testfile in os.listdir(TEST_DIR): | ||||
| def _make_testfunc(testfile): | ||||
|     m = re.match(r'^(.*)\.(as)$', testfile) | ||||
|     if not m: | ||||
|         continue | ||||
|         return | ||||
|     test_id = m.group(1) | ||||
|  | ||||
|     def test_func(self): | ||||
| @@ -36,7 +36,7 @@ for testfile in os.listdir(TEST_DIR): | ||||
|                 or os.path.getmtime(swf_file) < os.path.getmtime(as_file)): | ||||
|             # Recompile | ||||
|             try: | ||||
|                 subprocess.check_call(['mxmlc', '--output', swf_file, as_file]) | ||||
|                 subprocess.check_call(['mxmlc', '-output', swf_file, as_file]) | ||||
|             except OSError as ose: | ||||
|                 if ose.errno == errno.ENOENT: | ||||
|                     print('mxmlc not found! Skipping test.') | ||||
| @@ -69,5 +69,8 @@ for testfile in os.listdir(TEST_DIR): | ||||
|     setattr(TestSWFInterpreter, test_func.__name__, test_func) | ||||
|  | ||||
|  | ||||
| for testfile in os.listdir(TEST_DIR): | ||||
|     _make_testfunc(testfile) | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|     unittest.main() | ||||
|   | ||||
| @@ -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() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Philipp Hagemeister
					Philipp Hagemeister