mirror of
https://github.com/ytdl-org/youtube-dl
synced 2025-07-13 23:14:13 +09:00
Compare commits
2 Commits
66e58dccc2
...
d619dd712f
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d619dd712f | ||
![]() |
573b13410e |
@ -192,6 +192,31 @@ class TestJSInterpreter(unittest.TestCase):
|
|||||||
''')
|
''')
|
||||||
self.assertEqual(jsi.call_function('x'), 10)
|
self.assertEqual(jsi.call_function('x'), 10)
|
||||||
|
|
||||||
|
def test_catch(self):
|
||||||
|
jsi = JSInterpreter('''
|
||||||
|
function x() { try{throw 10} catch(e){return 5} }
|
||||||
|
''')
|
||||||
|
self.assertEqual(jsi.call_function('x'), 5)
|
||||||
|
|
||||||
|
@unittest.expectedFailure
|
||||||
|
def test_finally(self):
|
||||||
|
jsi = JSInterpreter('''
|
||||||
|
function x() { try{throw 10} finally {return 42} }
|
||||||
|
''')
|
||||||
|
self.assertEqual(jsi.call_function('x'), 42)
|
||||||
|
jsi = JSInterpreter('''
|
||||||
|
function x() { try{throw 10} catch(e){return 5} finally {return 42} }
|
||||||
|
''')
|
||||||
|
self.assertEqual(jsi.call_function('x'), 42)
|
||||||
|
|
||||||
|
def test_nested_try(self):
|
||||||
|
jsi = JSInterpreter('''
|
||||||
|
function x() {try {
|
||||||
|
try{throw 10} finally {throw 42}
|
||||||
|
} catch(e){return 5} }
|
||||||
|
''')
|
||||||
|
self.assertEqual(jsi.call_function('x'), 5)
|
||||||
|
|
||||||
def test_for_loop_continue(self):
|
def test_for_loop_continue(self):
|
||||||
jsi = JSInterpreter('''
|
jsi = JSInterpreter('''
|
||||||
function x() { a=0; for (i=0; i-10; i++) { continue; a++ } return a }
|
function x() { a=0; for (i=0; i-10; i++) { continue; a++ } return a }
|
||||||
|
@ -111,6 +111,10 @@ _NSIG_TESTS = [
|
|||||||
'https://www.youtube.com/s/player/1f7d5369/player_ias.vflset/en_US/base.js',
|
'https://www.youtube.com/s/player/1f7d5369/player_ias.vflset/en_US/base.js',
|
||||||
'batNX7sYqIJdkJ', 'IhOkL_zxbkOZBw',
|
'batNX7sYqIJdkJ', 'IhOkL_zxbkOZBw',
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
'https://www.youtube.com/s/player/dc0c6770/player_ias.vflset/en_US/base.js',
|
||||||
|
'5EHDMgYLV6HPGk_Mu-kk', 'n9lUJLHbxUI0GQ',
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -1500,7 +1500,8 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
return lambda s: jsi.extract_function_from_code(*func_code)([s])
|
return lambda s: jsi.extract_function_from_code(*func_code)([s])
|
||||||
|
|
||||||
def _n_descramble(self, n_param, player_url, video_id):
|
def _n_descramble(self, n_param, player_url, video_id):
|
||||||
"""Compute the response to YT's "n" parameter challenge
|
"""Compute the response to YT's "n" parameter challenge,
|
||||||
|
or None
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
n_param -- challenge string that is the value of the
|
n_param -- challenge string that is the value of the
|
||||||
@ -1518,7 +1519,10 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
if player_id not in self._player_cache:
|
if player_id not in self._player_cache:
|
||||||
self._player_cache[player_id] = self._extract_n_function(video_id, player_url)
|
self._player_cache[player_id] = self._extract_n_function(video_id, player_url)
|
||||||
func = self._player_cache[player_id]
|
func = self._player_cache[player_id]
|
||||||
self._player_cache[sig_id] = func(n_param)
|
ret = func(n_param)
|
||||||
|
if ret.startswith('enhanced_except_'):
|
||||||
|
raise ExtractorError('Unhandled exception in decode')
|
||||||
|
self._player_cache[sig_id] = ret
|
||||||
if self._downloader.params.get('verbose', False):
|
if self._downloader.params.get('verbose', False):
|
||||||
self._downloader.to_screen('[debug] [%s] %s' % (self.IE_NAME, 'Decrypted nsig {0} => {1}'.format(n_param, self._player_cache[sig_id])))
|
self._downloader.to_screen('[debug] [%s] %s' % (self.IE_NAME, 'Decrypted nsig {0} => {1}'.format(n_param, self._player_cache[sig_id])))
|
||||||
return self._player_cache[sig_id]
|
return self._player_cache[sig_id]
|
||||||
@ -1539,10 +1543,12 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
continue
|
continue
|
||||||
n_param = n_param[-1]
|
n_param = n_param[-1]
|
||||||
n_response = self._n_descramble(n_param, player_url, video_id)
|
n_response = self._n_descramble(n_param, player_url, video_id)
|
||||||
if n_response:
|
if n_response is None:
|
||||||
qs['n'] = [n_response]
|
# give up if descrambling failed
|
||||||
fmt['url'] = compat_urlparse.urlunparse(
|
break
|
||||||
parsed_fmt_url._replace(query=compat_urllib_parse_urlencode(qs, True)))
|
qs['n'] = [n_response]
|
||||||
|
fmt['url'] = compat_urlparse.urlunparse(
|
||||||
|
parsed_fmt_url._replace(query=compat_urllib_parse_urlencode(qs, True)))
|
||||||
|
|
||||||
def _mark_watched(self, video_id, player_response):
|
def _mark_watched(self, video_id, player_response):
|
||||||
playback_url = url_or_none(try_get(
|
playback_url = url_or_none(try_get(
|
||||||
|
@ -5,6 +5,7 @@ import json
|
|||||||
import math
|
import math
|
||||||
import operator
|
import operator
|
||||||
import re
|
import re
|
||||||
|
from collections import Counter
|
||||||
|
|
||||||
from .utils import (
|
from .utils import (
|
||||||
error_to_compat_str,
|
error_to_compat_str,
|
||||||
@ -108,8 +109,8 @@ _OPERATORS = (
|
|||||||
|
|
||||||
_COMP_OPERATORS = (
|
_COMP_OPERATORS = (
|
||||||
('===', operator.is_),
|
('===', operator.is_),
|
||||||
('==', _js_eq_op(operator.eq)),
|
|
||||||
('!==', operator.is_not),
|
('!==', operator.is_not),
|
||||||
|
('==', _js_eq_op(operator.eq)),
|
||||||
('!=', _js_eq_op(operator.ne)),
|
('!=', _js_eq_op(operator.ne)),
|
||||||
('<=', _js_comp_op(operator.le)),
|
('<=', _js_comp_op(operator.le)),
|
||||||
('>=', _js_comp_op(operator.ge)),
|
('>=', _js_comp_op(operator.ge)),
|
||||||
@ -241,7 +242,9 @@ class JSInterpreter(object):
|
|||||||
def _separate(cls, expr, delim=',', max_split=None, skip_delims=None):
|
def _separate(cls, expr, delim=',', max_split=None, skip_delims=None):
|
||||||
if not expr:
|
if not expr:
|
||||||
return
|
return
|
||||||
|
# collections.Counter() is ~10% slower
|
||||||
counters = {k: 0 for k in _MATCHING_PARENS.values()}
|
counters = {k: 0 for k in _MATCHING_PARENS.values()}
|
||||||
|
# counters = Counter()
|
||||||
start, splits, pos, delim_len = 0, 0, 0, len(delim) - 1
|
start, splits, pos, delim_len = 0, 0, 0, len(delim) - 1
|
||||||
in_quote, escaping, skipping = None, False, 0
|
in_quote, escaping, skipping = None, False, 0
|
||||||
after_op, in_regex_char_group, skip_re = True, False, 0
|
after_op, in_regex_char_group, skip_re = True, False, 0
|
||||||
@ -442,6 +445,7 @@ class JSInterpreter(object):
|
|||||||
return ret, should_abort or should_return
|
return ret, should_abort or should_return
|
||||||
|
|
||||||
elif md.get('catch'):
|
elif md.get('catch'):
|
||||||
|
|
||||||
catch_expr, expr = self._separate_at_paren(expr[m.end():], '}')
|
catch_expr, expr = self._separate_at_paren(expr[m.end():], '}')
|
||||||
if self._EXC_NAME in local_vars:
|
if self._EXC_NAME in local_vars:
|
||||||
catch_vars = local_vars.new_child({m.group('err'): local_vars.pop(self._EXC_NAME)})
|
catch_vars = local_vars.new_child({m.group('err'): local_vars.pop(self._EXC_NAME)})
|
||||||
@ -450,6 +454,7 @@ class JSInterpreter(object):
|
|||||||
return ret, True
|
return ret, True
|
||||||
|
|
||||||
ret, should_abort = self.interpret_statement(expr, local_vars, allow_recursion)
|
ret, should_abort = self.interpret_statement(expr, local_vars, allow_recursion)
|
||||||
|
|
||||||
return ret, should_abort or should_return
|
return ret, should_abort or should_return
|
||||||
|
|
||||||
elif md.get('for'):
|
elif md.get('for'):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user