]> jfr.im git - yt-dlp.git/commitdiff
[jsinterp] Handle default in switch better
authorpukkandan <redacted>
Wed, 3 Nov 2021 10:55:48 +0000 (16:25 +0530)
committerpukkandan <redacted>
Wed, 3 Nov 2021 11:05:08 +0000 (16:35 +0530)
test/test_jsinterp.py
test/test_youtube_signature.py
yt_dlp/jsinterp.py

index 380e52c3333507a292395a59b07ea76c0ede43bf..e230b045fd325028bf345bdf93fddc825a79be4a 100644 (file)
@@ -132,6 +132,21 @@ def test_switch(self):
         self.assertEqual(jsi.call_function('x', 3), 6)
         self.assertEqual(jsi.call_function('x', 5), 0)
 
+    def test_switch_default(self):
+        jsi = JSInterpreter('''
+        function x(f) { switch(f){
+            case 2: f+=2;
+            default: f-=1;
+            case 5:
+            case 6: f+=6;
+            case 0: break;
+            case 1: f+=1;
+        } return f }
+        ''')
+        self.assertEqual(jsi.call_function('x', 1), 2)
+        self.assertEqual(jsi.call_function('x', 5), 11)
+        self.assertEqual(jsi.call_function('x', 9), 14)
+
     def test_try(self):
         jsi = JSInterpreter('''
         function x() { try{return 10} catch(e){return 5} }
index f40a0695262cdf074e9159bebf44e347205cc7d9..60d8eabf5ce40bd427d4741ee966d9be6725ca18 100644 (file)
     (
         'https://www.youtube.com/s/player/9216d1f7/player_ias.vflset/en_US/base.js',
         'SLp9F5bwjAdhE9F-', 'gWnb9IK2DJ8Q1w',
-    ),  # TODO: Add more tests
+    ),
+    (
+        'https://www.youtube.com/s/player/f8cb7a3b/player_ias.vflset/en_US/base.js',
+        'oBo2h5euWy6osrUt', 'ivXHpm7qJjJN',
+    ),
 ]
 
 
index 5c79a8110de4e32a96b3485d3614c54e8bf0b456..bb2a0ae0b9f8902d2546c461f94cae5e491f3088 100644 (file)
@@ -228,21 +228,25 @@ def interpret_expression(self, expr, local_vars, allow_recursion):
             switch_val, remaining = self._seperate_at_paren(expr[m.end() - 1:], ')')
             switch_val = self.interpret_expression(switch_val, local_vars, allow_recursion)
             body, expr = self._seperate_at_paren(remaining, '}')
-            body, default = body.split('default:') if 'default:' in body else (body, None)
-            items = body.split('case ')[1:]
-            if default:
-                items.append(f'default:{default}')
-            matched = False
-            for item in items:
-                case, stmt = [i.strip() for i in self._seperate(item, ':', 1)]
-                matched = matched or case == 'default' or switch_val == self.interpret_expression(case, local_vars, allow_recursion)
-                if matched:
+            items = body.replace('default:', 'case default:').split('case ')[1:]
+            for default in (False, True):
+                matched = False
+                for item in items:
+                    case, stmt = [i.strip() for i in self._seperate(item, ':', 1)]
+                    if default:
+                        matched = matched or case == 'default'
+                    elif not matched:
+                        matched = case != 'default' and switch_val == self.interpret_expression(case, local_vars, allow_recursion)
+                    if not matched:
+                        continue
                     try:
                         ret, should_abort = self.interpret_statement(stmt, local_vars, allow_recursion - 1)
                         if should_abort:
                             return ret
                     except JS_Break:
                         break
+                if matched:
+                    break
             return self.interpret_statement(expr, local_vars, allow_recursion - 1)[0]
 
         # Comma seperated statements