mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-10-31 06:35:12 +00:00 
			
		
		
		
	| @@ -4,7 +4,7 @@ import json | ||||
| import operator | ||||
| import re | ||||
| 
 | ||||
| from .utils import ExtractorError, remove_quotes | ||||
| from .utils import ExtractorError, remove_quotes, truncate_string | ||||
| 
 | ||||
| _NAME_RE = r'[a-zA-Z_$][\w$]*' | ||||
| _OPERATORS = { | ||||
| @@ -53,6 +53,12 @@ class JSInterpreter: | ||||
|         self.code, self._functions = code, {} | ||||
|         self._objects = {} if objects is None else objects | ||||
| 
 | ||||
|     class Exception(ExtractorError): | ||||
|         def __init__(self, msg, expr=None, *args, **kwargs): | ||||
|             if expr is not None: | ||||
|                 msg += f' in: {truncate_string(expr, 50, 50)}' | ||||
|             super().__init__(msg, *args, **kwargs) | ||||
| 
 | ||||
|     def _named_object(self, namespace, obj): | ||||
|         self.__named_object_counter += 1 | ||||
|         name = f'__yt_dlp_jsinterp_obj{self.__named_object_counter}' | ||||
| @@ -92,12 +98,12 @@ class JSInterpreter: | ||||
|     def _separate_at_paren(cls, expr, delim): | ||||
|         separated = list(cls._separate(expr, delim, 1)) | ||||
|         if len(separated) < 2: | ||||
|             raise ExtractorError(f'No terminating paren {delim} in {expr}') | ||||
|             raise cls.Exception(f'No terminating paren {delim}', expr) | ||||
|         return separated[0][1:].strip(), separated[1].strip() | ||||
| 
 | ||||
|     def interpret_statement(self, stmt, local_vars, allow_recursion=100): | ||||
|         if allow_recursion < 0: | ||||
|             raise ExtractorError('Recursion limit reached') | ||||
|             raise self.Exception('Recursion limit reached') | ||||
| 
 | ||||
|         should_abort = False | ||||
|         sub_statements = list(self._separate(stmt, ';')) or [''] | ||||
| @@ -177,8 +183,7 @@ class JSInterpreter: | ||||
|                     body, expr = remaining, '' | ||||
|             start, cndn, increment = self._separate(constructor, ';') | ||||
|             if self.interpret_statement(start, local_vars, allow_recursion - 1)[1]: | ||||
|                 raise ExtractorError( | ||||
|                     f'Premature return in the initialization of a for loop in {constructor!r}') | ||||
|                 raise self.Exception('Premature return in the initialization of a for loop', constructor) | ||||
|             while True: | ||||
|                 if not self.interpret_expression(cndn, local_vars, allow_recursion): | ||||
|                     break | ||||
| @@ -191,8 +196,7 @@ class JSInterpreter: | ||||
|                 except JS_Continue: | ||||
|                     pass | ||||
|                 if self.interpret_statement(increment, local_vars, allow_recursion - 1)[1]: | ||||
|                     raise ExtractorError( | ||||
|                         f'Premature return in the initialization of a for loop in {constructor!r}') | ||||
|                     raise self.Exception('Premature return in the initialization of a for loop', constructor) | ||||
|             return self.interpret_statement(expr, local_vars, allow_recursion - 1)[0] | ||||
| 
 | ||||
|         elif m and m.group('switch'): | ||||
| @@ -267,11 +271,11 @@ class JSInterpreter: | ||||
|                 local_vars[m.group('out')] = opfunc(left_val, right_val) | ||||
|                 return local_vars[m.group('out')] | ||||
|             elif left_val is None: | ||||
|                 raise ExtractorError(f'Cannot index undefined variable: {m.group("out")}') | ||||
|                 raise self.Exception(f'Cannot index undefined variable {m.group("out")}', expr) | ||||
| 
 | ||||
|             idx = self.interpret_expression(m.group('index'), local_vars, allow_recursion) | ||||
|             if not isinstance(idx, int): | ||||
|                 raise ExtractorError(f'List indices must be integers: {idx}') | ||||
|                 raise self.Exception(f'List index {idx} must be integer', expr) | ||||
|             left_val[idx] = opfunc(left_val[idx], right_val) | ||||
|             return left_val[idx] | ||||
| 
 | ||||
| @@ -303,11 +307,11 @@ class JSInterpreter: | ||||
|             left_val, should_abort = self.interpret_statement( | ||||
|                 left_val, local_vars, allow_recursion - 1) | ||||
|             if should_abort: | ||||
|                 raise ExtractorError(f'Premature left-side return of {op} in {expr!r}') | ||||
|                 raise self.Exception(f'Premature left-side return of {op}', expr) | ||||
|             right_val, should_abort = self.interpret_statement( | ||||
|                 right_val, local_vars, allow_recursion - 1) | ||||
|             if should_abort: | ||||
|                 raise ExtractorError(f'Premature right-side return of {op} in {expr!r}') | ||||
|                 raise self.Exception(f'Premature right-side return of {op}', expr) | ||||
|             return opfunc(left_val or 0, right_val) | ||||
| 
 | ||||
|         if m and m.group('attribute'): | ||||
| @@ -322,7 +326,7 @@ class JSInterpreter: | ||||
|             def assertion(cndn, msg): | ||||
|                 """ assert, but without risk of getting optimized out """ | ||||
|                 if not cndn: | ||||
|                     raise ExtractorError(f'{member} {msg}: {expr}') | ||||
|                     raise self.Exception(f'{member} {msg}', expr) | ||||
| 
 | ||||
|             def eval_method(): | ||||
|                 if variable == 'String': | ||||
| @@ -349,7 +353,7 @@ class JSInterpreter: | ||||
|                     if member == 'fromCharCode': | ||||
|                         assertion(argvals, 'takes one or more arguments') | ||||
|                         return ''.join(map(chr, argvals)) | ||||
|                     raise ExtractorError(f'Unsupported string method {member}') | ||||
|                     raise self.Exception(f'Unsupported string method {member}', expr) | ||||
| 
 | ||||
|                 if member == 'split': | ||||
|                     assertion(argvals, 'takes one or more arguments') | ||||
| @@ -430,7 +434,7 @@ class JSInterpreter: | ||||
|                 self._functions[fname] = self.extract_function(fname) | ||||
|             return self._functions[fname](argvals) | ||||
| 
 | ||||
|         raise ExtractorError(f'Unsupported JS expression {expr!r}') | ||||
|         raise self.Exception('Unsupported JS expression', expr) | ||||
| 
 | ||||
|     def extract_object(self, objname): | ||||
|         _FUNC_NAME_RE = r'''(?:[a-zA-Z$0-9]+|"[a-zA-Z$0-9]+"|'[a-zA-Z$0-9]+')''' | ||||
| @@ -469,7 +473,7 @@ class JSInterpreter: | ||||
|             self.code) | ||||
|         code, _ = self._separate_at_paren(func_m.group('code'), '}')  # refine the match | ||||
|         if func_m is None: | ||||
|             raise ExtractorError(f'Could not find JS function "{funcname}"') | ||||
|             raise self.Exception(f'Could not find JS function "{funcname}"') | ||||
|         return func_m.group('args').split(','), code | ||||
| 
 | ||||
|     def extract_function(self, funcname): | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 pukkandan
					pukkandan