]> jfr.im git - yt-dlp.git/commitdiff
[jsinterp] Add `charcodeAt` and bitwise overflow (#4706)
authorElyse <redacted>
Fri, 19 Aug 2022 05:30:04 +0000 (00:30 -0500)
committerpukkandan <redacted>
Wed, 31 Aug 2022 15:31:22 +0000 (21:01 +0530)
Authored by: elyse0

test/test_jsinterp.py
yt_dlp/jsinterp.py

index 778607fb259a18dec1aa447b8e0ef40502834aab..4b6e22bac27251f3d0291f168db6b244ee3bfec9 100644 (file)
@@ -352,6 +352,22 @@ def test_regex(self):
         ''')
         self.assertEqual(jsi.call_function('x').flags & re.I, re.I)
 
+    def test_char_code_at(self):
+        jsi = JSInterpreter('function x(i){return "test".charCodeAt(i)}')
+        self.assertEqual(jsi.call_function('x', 0), 116)
+        self.assertEqual(jsi.call_function('x', 1), 101)
+        self.assertEqual(jsi.call_function('x', 2), 115)
+        self.assertEqual(jsi.call_function('x', 3), 116)
+        self.assertEqual(jsi.call_function('x', 4), None)
+        self.assertEqual(jsi.call_function('x', 'not_a_number'), 116)
+
+    def test_bitwise_operators_overflow(self):
+        jsi = JSInterpreter('function x(){return -524999584 << 5}')
+        self.assertEqual(jsi.call_function('x'), 379882496)
+
+        jsi = JSInterpreter('function x(){return 1236566549 << 5}')
+        self.assertEqual(jsi.call_function('x'), 915423904)
+
 
 if __name__ == '__main__':
     unittest.main()
index 99bdca9270b2df77c396d25e680171ac86ebfecd..51c7beed433320bb2e8c6127bf9370693da582da 100644 (file)
 
 
 def _js_bit_op(op):
+    def zeroise(x):
+        return 0 if x in (None, JS_Undefined) else x
+
     def wrapped(a, b):
-        def zeroise(x):
-            return 0 if x in (None, JS_Undefined) else x
-        return op(zeroise(a), zeroise(b))
+        return op(zeroise(a), zeroise(b)) & 0xffffffff
 
     return wrapped
 
@@ -692,6 +693,13 @@ def eval_method():
                         return obj.index(idx, start)
                     except ValueError:
                         return -1
+                elif member == 'charCodeAt':
+                    assertion(isinstance(obj, str), 'must be applied on a string')
+                    assertion(len(argvals) == 1, 'takes exactly one argument')
+                    idx = argvals[0] if isinstance(argvals[0], int) else 0
+                    if idx >= len(obj):
+                        return None
+                    return ord(obj[idx])
 
                 idx = int(member) if isinstance(obj, list) else member
                 return obj[idx](argvals, allow_recursion=allow_recursion)