diff options
author | dirkf <fieldhouse@gmx.net> | 2025-04-04 12:29:28 +0100 |
---|---|---|
committer | dirkf <fieldhouse@gmx.net> | 2025-04-08 01:59:00 +0100 |
commit | bd2ded59f218bed637514f3aaf11787fa7b87ccf (patch) | |
tree | f4f052339443cbd59342fb26ce908088c0faf817 | |
parent | 16b7e97afad2ed73c2d01a55987cb323407ca1c4 (diff) |
[JSInterp] Improve unary operators; add `!`
-rw-r--r-- | test/test_jsinterp.py | 7 | ||||
-rw-r--r-- | youtube_dl/jsinterp.py | 9 |
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: |