Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[YouTube] Fix bit-shift coercion for player 9c6dfc4a #33049

Merged
merged 2 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions test/test_jsinterp.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,10 @@ def test_bitwise_operators_typecast(self):
self._test('function f(){return undefined >> 5}', 0)
self._test('function f(){return 42 << NaN}', 42)
self._test('function f(){return 42 << Infinity}', 42)
self._test('function f(){return 0.0 << null}', 0)
self._test('function f(){return NaN << 42}', 0)
self._test('function f(){return "21.9" << 1}', 42)
self._test('function f(){return 21 << 4294967297}', 42)

def test_negative(self):
self._test('function f(){return 2 * -2.0 ;}', -4)
Expand Down
4 changes: 4 additions & 0 deletions test/test_youtube_signature.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@
'https://www.youtube.com/s/player/2f1832d2/player_ias.vflset/en_US/base.js',
'YWt1qdbe8SAfkoPHW5d', 'RrRjWQOJmBiP',
),
(
'https://www.youtube.com/s/player/9c6dfc4a/player_ias.vflset/en_US/base.js',
'jbu7ylIosQHyJyJV', 'uwI0ESiynAmhNg',
),
]


Expand Down
12 changes: 4 additions & 8 deletions youtube_dl/casefold.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
# https://github.com/unicode-org/icu/blob/main/icu4c/source/data/unidata/CaseFolding.txt
# In case newly foldable Unicode characters are defined, paste the new version
# of the text inside the ''' marks.
# The text is expected to have only blank lines andlines with 1st character #,
# The text is expected to have only blank lines and lines with 1st character #,
# all ignored, and fold definitions like this:
# `from_hex_code; space_separated_to_hex_code_list; comment`
# `from_hex_code; status; space_separated_to_hex_code_list; comment`
# Only `status` C/F are used.

_map_str = '''
# CaseFolding-15.0.0.txt
Expand Down Expand Up @@ -1657,11 +1658,6 @@ def _parse_unichr(s):
del _map_str


def casefold(s):
def _casefold(s):
assert isinstance(s, compat_str)
return ''.join((_map.get(c, c) for c in s))


__all__ = [
'casefold',
]
7 changes: 6 additions & 1 deletion youtube_dl/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
compat_str.casefold
compat_casefold = lambda s: s.casefold()
except AttributeError:
from .casefold import casefold as compat_casefold
from .casefold import _casefold as compat_casefold

try:
import collections.abc as compat_collections_abc
Expand Down Expand Up @@ -3116,17 +3116,21 @@ def compat_kwargs(kwargs):
compat_kwargs = lambda kwargs: kwargs


# compat_numeric_types
try:
compat_numeric_types = (int, float, long, complex)
except NameError: # Python 3
compat_numeric_types = (int, float, complex)


# compat_integer_types
try:
compat_integer_types = (int, long)
except NameError: # Python 3
compat_integer_types = (int, )

# compat_int
compat_int = compat_integer_types[-1]

if sys.version_info < (2, 7):
def compat_socket_create_connection(address, timeout, source_address=None):
Expand Down Expand Up @@ -3532,6 +3536,7 @@ def compat_datetime_timedelta_total_seconds(td):
'compat_http_client',
'compat_http_server',
'compat_input',
'compat_int',
'compat_integer_types',
'compat_itertools_count',
'compat_itertools_zip_longest',
Expand Down
27 changes: 21 additions & 6 deletions youtube_dl/jsinterp.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
compat_collections_chain_map as ChainMap,
compat_contextlib_suppress,
compat_filter as filter,
compat_int,
compat_integer_types,
compat_itertools_zip_longest as zip_longest,
compat_map as map,
compat_numeric_types,
Expand Down Expand Up @@ -70,14 +72,27 @@ class JS_Undefined(object):
pass


def _js_bit_op(op):
def _js_bit_op(op, is_shift=False):

def zeroise(x):
return 0 if x in (None, JS_Undefined, _NaN, _Infinity) else x
def zeroise(x, is_shift_arg=False):
if isinstance(x, compat_integer_types):
return (x % 32) if is_shift_arg else (x & 0xffffffff)
try:
x = float(x)
if is_shift_arg:
x = int(x % 32)
elif x < 0:
x = -compat_int(-x % 0xffffffff)
else:
x = compat_int(x % 0xffffffff)
except (ValueError, TypeError):
# also here for int(NaN), including float('inf') % 32
x = 0
return x

@wraps_op(op)
def wrapped(a, b):
return op(zeroise(a), zeroise(b)) & 0xffffffff
return op(zeroise(a), zeroise(b, is_shift)) & 0xffffffff

return wrapped

Expand Down Expand Up @@ -253,8 +268,8 @@ def _js_typeof(expr):
# avoid dict to maintain order
# definition None => Defined in JSInterpreter._operator
_OPERATORS = (
('>>', _js_bit_op(operator.rshift)),
('<<', _js_bit_op(operator.lshift)),
('>>', _js_bit_op(operator.rshift, True)),
('<<', _js_bit_op(operator.lshift, True)),
('+', _js_add),
('-', _js_arith_op(operator.sub)),
('*', _js_arith_op(operator.mul)),
Expand Down