mirror of
https://github.com/ytdl-org/youtube-dl
synced 2025-07-13 15:04:14 +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)
|
||||
|
||||
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):
|
||||
jsi = JSInterpreter('''
|
||||
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',
|
||||
'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])
|
||||
|
||||
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:
|
||||
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:
|
||||
self._player_cache[player_id] = self._extract_n_function(video_id, player_url)
|
||||
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):
|
||||
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]
|
||||
@ -1539,10 +1543,12 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
||||
continue
|
||||
n_param = n_param[-1]
|
||||
n_response = self._n_descramble(n_param, player_url, video_id)
|
||||
if n_response:
|
||||
qs['n'] = [n_response]
|
||||
fmt['url'] = compat_urlparse.urlunparse(
|
||||
parsed_fmt_url._replace(query=compat_urllib_parse_urlencode(qs, True)))
|
||||
if n_response is None:
|
||||
# give up if descrambling failed
|
||||
break
|
||||
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):
|
||||
playback_url = url_or_none(try_get(
|
||||
|
@ -5,6 +5,7 @@ import json
|
||||
import math
|
||||
import operator
|
||||
import re
|
||||
from collections import Counter
|
||||
|
||||
from .utils import (
|
||||
error_to_compat_str,
|
||||
@ -108,8 +109,8 @@ _OPERATORS = (
|
||||
|
||||
_COMP_OPERATORS = (
|
||||
('===', operator.is_),
|
||||
('==', _js_eq_op(operator.eq)),
|
||||
('!==', operator.is_not),
|
||||
('==', _js_eq_op(operator.eq)),
|
||||
('!=', _js_eq_op(operator.ne)),
|
||||
('<=', _js_comp_op(operator.le)),
|
||||
('>=', _js_comp_op(operator.ge)),
|
||||
@ -241,7 +242,9 @@ class JSInterpreter(object):
|
||||
def _separate(cls, expr, delim=',', max_split=None, skip_delims=None):
|
||||
if not expr:
|
||||
return
|
||||
# collections.Counter() is ~10% slower
|
||||
counters = {k: 0 for k in _MATCHING_PARENS.values()}
|
||||
# counters = Counter()
|
||||
start, splits, pos, delim_len = 0, 0, 0, len(delim) - 1
|
||||
in_quote, escaping, skipping = None, 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
|
||||
|
||||
elif md.get('catch'):
|
||||
|
||||
catch_expr, expr = self._separate_at_paren(expr[m.end():], '}')
|
||||
if self._EXC_NAME in local_vars:
|
||||
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
|
||||
|
||||
ret, should_abort = self.interpret_statement(expr, local_vars, allow_recursion)
|
||||
|
||||
return ret, should_abort or should_return
|
||||
|
||||
elif md.get('for'):
|
||||
|
Loading…
x
Reference in New Issue
Block a user