projects
/
youtube-dl
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
650bd94
)
[jsinterp] Add support for quoted names and indexers (closes #13123, closes #13130)
author
Sergey M․
<dstftw@gmail.com>
Thu, 18 May 2017 15:18:33 +0000
(22:18 +0700)
committer
Sergey M․
<dstftw@gmail.com>
Thu, 18 May 2017 15:18:33 +0000
(22:18 +0700)
youtube_dl/jsinterp.py
patch
|
blob
|
history
diff --git
a/youtube_dl/jsinterp.py
b/youtube_dl/jsinterp.py
index 24cdec28c6cb2332232212d6bcf39d03edc27c7a..038910049d76e60f39b6b59a910fd30791cc4935 100644
(file)
--- a/
youtube_dl/jsinterp.py
+++ b/
youtube_dl/jsinterp.py
@@
-6,6
+6,7
@@
import re
from .utils import (
ExtractorError,
from .utils import (
ExtractorError,
+ remove_quotes,
)
_OPERATORS = [
)
_OPERATORS = [
@@
-57,7
+58,6
@@
class JSInterpreter(object):
def interpret_expression(self, expr, local_vars, allow_recursion):
expr = expr.strip()
def interpret_expression(self, expr, local_vars, allow_recursion):
expr = expr.strip()
-
if expr == '': # Empty expression
return None
if expr == '': # Empty expression
return None
@@
-121,11
+121,19
@@
class JSInterpreter(object):
pass
m = re.match(
pass
m = re.match(
- r'(?P<var>%s)\.(?P<member>[^(]+)(?:\(+(?P<args>[^()]*)\))?$' % _NAME_RE,
+ r'(?P<in>%s)\[(?P<idx>.+)\]$' % _NAME_RE, expr)
+ if m:
+ val = local_vars[m.group('in')]
+ idx = self.interpret_expression(
+ m.group('idx'), local_vars, allow_recursion - 1)
+ return val[idx]
+
+ m = re.match(
+ r'(?P<var>%s)(?:\.(?P<member>[^(]+)|\[(?P<member2>[^]]+)\])\s*(?:\(+(?P<args>[^()]*)\))?$' % _NAME_RE,
expr)
if m:
variable = m.group('var')
expr)
if m:
variable = m.group('var')
- member =
m.group('member'
)
+ member =
remove_quotes(m.group('member') or m.group('member2')
)
arg_str = m.group('args')
if variable in local_vars:
arg_str = m.group('args')
if variable in local_vars:
@@
-173,14
+181,6
@@
class JSInterpreter(object):
return obj[member](argvals)
return obj[member](argvals)
- m = re.match(
- r'(?P<in>%s)\[(?P<idx>.+)\]$' % _NAME_RE, expr)
- if m:
- val = local_vars[m.group('in')]
- idx = self.interpret_expression(
- m.group('idx'), local_vars, allow_recursion - 1)
- return val[idx]
-
for op, opfunc in _OPERATORS:
m = re.match(r'(?P<x>.+?)%s(?P<y>.+)' % re.escape(op), expr)
if not m:
for op, opfunc in _OPERATORS:
m = re.match(r'(?P<x>.+?)%s(?P<y>.+)' % re.escape(op), expr)
if not m:
@@
-211,21
+211,22
@@
class JSInterpreter(object):
raise ExtractorError('Unsupported JS expression %r' % expr)
def extract_object(self, objname):
raise ExtractorError('Unsupported JS expression %r' % 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]+')'''
obj = {}
obj_m = re.search(
(r'(?<!this\.)%s\s*=\s*\{' % re.escape(objname)) +
obj = {}
obj_m = re.search(
(r'(?<!this\.)%s\s*=\s*\{' % re.escape(objname)) +
- r'\s*(?P<fields>(
[a-zA-Z$0-9]+
\s*:\s*function\(.*?\)\s*\{.*?\}(?:,\s*)?)*)' +
- r'\}\s*;',
+ r'\s*(?P<fields>(
%s
\s*:\s*function\(.*?\)\s*\{.*?\}(?:,\s*)?)*)' +
+ r'\}\s*;'
% _FUNC_NAME_RE
,
self.code)
fields = obj_m.group('fields')
# Currently, it only supports function definitions
fields_m = re.finditer(
self.code)
fields = obj_m.group('fields')
# Currently, it only supports function definitions
fields_m = re.finditer(
- r'(?P<key>
[a-zA-Z$0-9]+
)\s*:\s*function'
- r'\((?P<args>[a-z,]+)\){(?P<code>[^}]+)}',
+ r'(?P<key>
%s
)\s*:\s*function'
+ r'\((?P<args>[a-z,]+)\){(?P<code>[^}]+)}'
% _FUNC_NAME_RE
,
fields)
for f in fields_m:
argnames = f.group('args').split(',')
fields)
for f in fields_m:
argnames = f.group('args').split(',')
- obj[
f.group('key'
)] = self.build_function(argnames, f.group('code'))
+ obj[
remove_quotes(f.group('key')
)] = self.build_function(argnames, f.group('code'))
return obj
return obj