[BUGFIX] Properly sanitize override variables after it is resolved

This commit is contained in:
Jesse Bannon 2022-09-07 23:05:53 -07:00
parent 4b2e6e1169
commit dd11f0638c
2 changed files with 43 additions and 14 deletions

View file

@ -5,6 +5,8 @@ from typing import Dict
from typing import List from typing import List
from typing import final from typing import final
from yt_dlp.utils import sanitize_filename
from ytdl_sub.utils.exceptions import InvalidVariableNameException from ytdl_sub.utils.exceptions import InvalidVariableNameException
from ytdl_sub.utils.exceptions import StringFormattingException from ytdl_sub.utils.exceptions import StringFormattingException
from ytdl_sub.utils.exceptions import StringFormattingVariableNotFoundException from ytdl_sub.utils.exceptions import StringFormattingVariableNotFoundException
@ -151,24 +153,23 @@ class StringFormatterValidator(Validator):
value=formatter.format_string.format(**OrderedDict(variable_dict)), value=formatter.format_string.format(**OrderedDict(variable_dict)),
) )
def apply_formatter(self, variable_dict: Dict[str, str]) -> str: def _apply_formatter(self, variable_dict: Dict[str, str], resolve_sanitized: bool = False):
"""
Calls `format` on the format string using the variable_dict as input kwargs
Parameters
----------
variable_dict
kwargs to pass to the format string
Returns
-------
Format string formatted
"""
# Keep formatting the format string until no format_variables are present
formatter = self formatter = self
recursion_depth = 0 recursion_depth = 0
max_depth = self._max_format_recursion max_depth = self._max_format_recursion
if resolve_sanitized:
for format_variable in formatter.format_variables:
# Must resolve the sanitized variable completely
if format_variable.endswith("_sanitized"):
# pylint: disable=protected-access
variable_dict[format_variable] = sanitize_filename(
StringFormatterValidator(
name=self._name, value=f"{{{format_variable}}}"
)._apply_formatter(variable_dict, resolve_sanitized=False)
)
# pylint: enable=protected-access
while formatter.format_variables and recursion_depth < max_depth: while formatter.format_variables and recursion_depth < max_depth:
formatter = self.__apply_formatter(formatter=formatter, variable_dict=variable_dict) formatter = self.__apply_formatter(formatter=formatter, variable_dict=variable_dict)
recursion_depth += 1 recursion_depth += 1
@ -183,6 +184,21 @@ class StringFormatterValidator(Validator):
return formatter.format_string return formatter.format_string
def apply_formatter(self, variable_dict: Dict[str, str]) -> str:
"""
Calls `format` on the format string using the variable_dict as input kwargs
Parameters
----------
variable_dict
kwargs to pass to the format string
Returns
-------
Format string formatted
"""
return self._apply_formatter(variable_dict=variable_dict, resolve_sanitized=True)
# pylint: disable=line-too-long # pylint: disable=line-too-long
class OverridesStringFormatterValidator(StringFormatterValidator): class OverridesStringFormatterValidator(StringFormatterValidator):

View file

@ -1,4 +1,5 @@
import pytest import pytest
from yt_dlp.utils import sanitize_filename
from ytdl_sub.utils.exceptions import StringFormattingException from ytdl_sub.utils.exceptions import StringFormattingException
from ytdl_sub.utils.exceptions import ValidationException from ytdl_sub.utils.exceptions import ValidationException
@ -146,6 +147,18 @@ class TestStringFormatterValidator(object):
assert format_string.apply_formatter(variable_dict=variable_dict) == expected_string assert format_string.apply_formatter(variable_dict=variable_dict) == expected_string
def test_entry_formatter_override_sanitized_recursive(self, string_formatter_class):
variable_dict = {
"level_a": "level a",
"level_b": "level b ? {level_a}",
"level_c_sanitized": "level c and {level_b}",
}
format_string = string_formatter_class(name="test", value="level d and {level_c_sanitized}")
expected_string = "level d and " + sanitize_filename("level c and level b ? level a")
assert format_string.apply_formatter(variable_dict=variable_dict) == expected_string
def test_entry_formatter_override_recursive_fail_cycle(self, string_formatter_class): def test_entry_formatter_override_recursive_fail_cycle(self, string_formatter_class):
variable_dict = { variable_dict = {
"level_a": "{level_b}", "level_a": "{level_b}",