aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordirkf <fieldhouse@gmx.net>2025-04-04 12:29:28 +0100
committerdirkf <fieldhouse@gmx.net>2025-04-08 01:59:00 +0100
commitbd2ded59f218bed637514f3aaf11787fa7b87ccf (patch)
treef4f052339443cbd59342fb26ce908088c0faf817
parent16b7e97afad2ed73c2d01a55987cb323407ca1c4 (diff)
[JSInterp] Improve unary operators; add `!`
-rw-r--r--test/test_jsinterp.py7
-rw-r--r--youtube_dl/jsinterp.py9
2 files changed, 13 insertions, 3 deletions
diff --git a/test/test_jsinterp.py b/test/test_jsinterp.py
index 30c48adfc..95bac75d7 100644
--- a/test/test_jsinterp.py
+++ b/test/test_jsinterp.py
@@ -371,6 +371,13 @@ class TestJSInterpreter(unittest.TestCase):
self._test('function f() { a=5; return (a -= 1, a+=3, a); }', 7)
self._test('function f() { return (l=[0,1,2,3], function(a, b){return a+b})((l[1], l[2]), l[3]) }', 5)
+ def test_not(self):
+ self._test('function f() { return ! undefined; }', True)
+ self._test('function f() { return !0; }', True)
+ self._test('function f() { return !!0; }', False)
+ self._test('function f() { return ![]; }', False)
+ self._test('function f() { return !0 !== false; }', True)
+
def test_void(self):
self._test('function f() { return void 42; }', JS_Undefined)
diff --git a/youtube_dl/jsinterp.py b/youtube_dl/jsinterp.py
index 3824a0f6b..ff9894f52 100644
--- a/youtube_dl/jsinterp.py
+++ b/youtube_dl/jsinterp.py
@@ -240,7 +240,7 @@ def _js_ternary(cndn, if_true=True, if_false=False):
def _js_unary_op(op):
@wraps_op(op)
- def wrapped(_, a):
+ def wrapped(a, _):
return op(a)
return wrapped
@@ -299,6 +299,8 @@ _SC_OPERATORS = (
_UNARY_OPERATORS_X = (
('void', _js_unary_op(lambda _: JS_Undefined)),
('typeof', _js_unary_op(_js_typeof)),
+ # avoid functools.partial here since Py2 update_wrapper(partial) -> no __module__
+ ('!', _js_unary_op(lambda x: _js_ternary(x, if_true=False, if_false=True))),
)
_OPERATOR_RE = '|'.join(map(lambda x: re.escape(x[0]), _OPERATORS + _LOG_OPERATORS))
@@ -776,7 +778,7 @@ class JSInterpreter(object):
elif op == '?':
right_expr = _js_ternary(left_val, *self._separate(right_expr, ':', 1))
- right_val = self.interpret_expression(right_expr, local_vars, allow_recursion)
+ right_val = self.interpret_expression(right_expr, local_vars, allow_recursion) if right_expr else left_val
opfunc = op and next((v for k, v in self._all_operators() if k == op), None)
if not opfunc:
return right_val
@@ -879,11 +881,12 @@ class JSInterpreter(object):
else:
raise self.Exception('Unsupported object {obj:.100}'.format(**locals()), expr=expr)
+ # apply unary operators (see new above)
for op, _ in _UNARY_OPERATORS_X:
if not expr.startswith(op):
continue
operand = expr[len(op):]
- if not operand or operand[0] != ' ':
+ if not operand or (op.isalpha() and operand[0] != ' '):
continue
separated = self._separate_at_op(operand, max_split=1)
if separated: