Skip to content

Commit

Permalink
[utils] js_to_json: Implement template strings (yt-dlp#6623)
Browse files Browse the repository at this point in the history
Authored by: Grub4K
  • Loading branch information
Grub4K authored Mar 25, 2023
1 parent f68434c commit 0898c5c
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 2 deletions.
7 changes: 7 additions & 0 deletions test/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1190,6 +1190,13 @@ def test_js_to_json_malformed(self):
self.assertEqual(js_to_json('42a1'), '42"a1"')
self.assertEqual(js_to_json('42a-1'), '42"a"-1')

def test_js_to_json_template_literal(self):
self.assertEqual(js_to_json('`Hello ${name}`', {'name': '"world"'}), '"Hello world"')
self.assertEqual(js_to_json('`${name}${name}`', {'name': '"X"'}), '"XX"')
self.assertEqual(js_to_json('`${name}${name}`', {'name': '5'}), '"55"')
self.assertEqual(js_to_json('`${name}"${name}"`', {'name': '5'}), '"5\\"5\\""')
self.assertEqual(js_to_json('`${name}`', {}), '"name"')

def test_extract_attributes(self):
self.assertEqual(extract_attributes('<e x="y">'), {'x': 'y'})
self.assertEqual(extract_attributes("<e x='y'>"), {'x': 'y'})
Expand Down
11 changes: 9 additions & 2 deletions yt_dlp/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3366,7 +3366,7 @@ def strip_jsonp(code):

def js_to_json(code, vars={}, *, strict=False):
# vars is a dict of var, val pairs to substitute
STRING_QUOTES = '\'"'
STRING_QUOTES = '\'"`'
STRING_RE = '|'.join(rf'{q}(?:\\.|[^\\{q}])*{q}' for q in STRING_QUOTES)
COMMENT_RE = r'/\*(?:(?!\*/).)*?\*/|//[^\n]*\n'
SKIP_RE = fr'\s*(?:{COMMENT_RE})?\s*'
Expand All @@ -3384,6 +3384,12 @@ def process_escape(match):
else '' if escape == '\n'
else escape)

def template_substitute(match):
evaluated = js_to_json(match.group(1), vars, strict=strict)
if evaluated[0] == '"':
return json.loads(evaluated)
return evaluated

def fix_kv(m):
v = m.group(0)
if v in ('true', 'false', 'null'):
Expand All @@ -3394,7 +3400,8 @@ def fix_kv(m):
return ''

if v[0] in STRING_QUOTES:
escaped = re.sub(r'(?s)(")|\\(.)', process_escape, v[1:-1])
v = re.sub(r'(?s)\${([^}]+)}', template_substitute, v[1:-1]) if v[0] == '`' else v[1:-1]
escaped = re.sub(r'(?s)(")|\\(.)', process_escape, v)
return f'"{escaped}"'

for regex, base in INTEGER_TABLE:
Expand Down

0 comments on commit 0898c5c

Please sign in to comment.