Prechádzať zdrojové kódy

[jsinterp] Support functionality for player `b22ef6e7`
* support `prototype` for call() and apply() (yt-dlp/yt-dlp#10392, thx Grub4k)
* map JS `Array` to `list`

dirkf 1 rok pred
rodič
commit
d35ce6ce95
2 zmenil súbory, kde vykonal 21 pridanie a 3 odobranie
  1. 0 0
      test/test_jsinterp.py
  2. 21 3
      youtube_dl/jsinterp.py

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 0
test/test_jsinterp.py


+ 21 - 3
youtube_dl/jsinterp.py

@@ -850,7 +850,7 @@ class JSInterpreter(object):
                     memb = member
                     memb = member
                     raise self.Exception('{memb} {msg}'.format(**locals()), expr=expr)
                     raise self.Exception('{memb} {msg}'.format(**locals()), expr=expr)
 
 
-            def eval_method():
+            def eval_method(variable, member):
                 if (variable, member) == ('console', 'debug'):
                 if (variable, member) == ('console', 'debug'):
                     if Debugger.ENABLED:
                     if Debugger.ENABLED:
                         Debugger.write(self.interpret_expression('[{}]'.format(arg_str), local_vars, allow_recursion))
                         Debugger.write(self.interpret_expression('[{}]'.format(arg_str), local_vars, allow_recursion))
@@ -858,6 +858,7 @@ class JSInterpreter(object):
                 types = {
                 types = {
                     'String': compat_str,
                     'String': compat_str,
                     'Math': float,
                     'Math': float,
+                    'Array': list,
                 }
                 }
                 obj = local_vars.get(variable)
                 obj = local_vars.get(variable)
                 if obj in (JS_Undefined, None):
                 if obj in (JS_Undefined, None):
@@ -883,6 +884,23 @@ class JSInterpreter(object):
                     self.interpret_expression(v, local_vars, allow_recursion)
                     self.interpret_expression(v, local_vars, allow_recursion)
                     for v in self._separate(arg_str)]
                     for v in self._separate(arg_str)]
 
 
+                # Fixup prototype call
+                if isinstance(obj, type):
+                    new_member, rest = member.partition('.')[0::2]
+                    if new_member == 'prototype':
+                        new_member, func_prototype = rest.partition('.')[0::2]
+                        assertion(argvals, 'takes one or more arguments')
+                        assertion(isinstance(argvals[0], obj), 'must bind to type {0}'.format(obj))
+                        if func_prototype == 'call':
+                            obj = argvals.pop(0)
+                        elif func_prototype == 'apply':
+                            assertion(len(argvals) == 2, 'takes two arguments')
+                            obj, argvals = argvals
+                            assertion(isinstance(argvals, list), 'second argument must be a list')
+                        else:
+                            raise self.Exception('Unsupported Function method ' + func_prototype, expr)
+                        member = new_member
+
                 if obj is compat_str:
                 if obj is compat_str:
                     if member == 'fromCharCode':
                     if member == 'fromCharCode':
                         assertion(argvals, 'takes one or more arguments')
                         assertion(argvals, 'takes one or more arguments')
@@ -976,11 +994,11 @@ class JSInterpreter(object):
 
 
             if remaining:
             if remaining:
                 ret, should_abort = self.interpret_statement(
                 ret, should_abort = self.interpret_statement(
-                    self._named_object(local_vars, eval_method()) + remaining,
+                    self._named_object(local_vars, eval_method(variable, member)) + remaining,
                     local_vars, allow_recursion)
                     local_vars, allow_recursion)
                 return ret, should_return or should_abort
                 return ret, should_return or should_abort
             else:
             else:
-                return eval_method(), should_return
+                return eval_method(variable, member), should_return
 
 
         elif md.get('function'):
         elif md.get('function'):
             fname = m.group('fname')
             fname = m.group('fname')

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov