commit: e1eae16b56b5c57e341b000167c0a92e67095e6e
parent 96f87aaa3b34d80bc72097a7475d8093849091fc
Author: df <fieldhouse@gmx.net>
Date: Thu, 4 Nov 2021 12:48:06 +0000
Handle default in switch better
Add https://github.com/yt-dlp/yt-dlp/commit/a1fc7ca0743c8df06416e68ee74b64e07dfe7135
Thanks coletdjnz
Diffstat:
2 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/test/test_jsinterp.py b/test/test_jsinterp.py
@@ -133,6 +133,21 @@ class TestJSInterpreter(unittest.TestCase):
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} }
diff --git a/youtube_dl/jsinterp.py b/youtube_dl/jsinterp.py
@@ -240,21 +240,26 @@ class JSInterpreter(object):
switch_val, remaining = self._separate_at_paren(expr[m.end() - 1:], ')')
switch_val = self.interpret_expression(switch_val, local_vars, allow_recursion)
body, expr = self._separate_at_paren(remaining, '}')
- body, default = body.split('default:') if 'default:' in body else (body, None)
- items = body.split('case ')[1:]
- if default:
- items.append('default:%s' % (default, ))
- matched = False
- for item in items:
- case, stmt = [i.strip() for i in self._separate(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._separate(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 separated statements