Skip to content

Commit a2808fa

Browse files
authored
[BACKEND] Properly sanitize recursive variables (#477)
* [BACKEND] Properly sanitize recursive variables * lint * update tests
1 parent a4dc61e commit a2808fa

20 files changed

Lines changed: 69 additions & 60 deletions

src/ytdl_sub/validators/string_formatter_validators.py

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,24 @@ def format_string(self) -> str:
134134
"""
135135
return self._value
136136

137-
def __apply_formatter(
137+
def _apply_formatter(
138138
self, formatter: "StringFormatterValidator", variable_dict: Dict[str, str]
139139
) -> "StringFormatterValidator":
140140
# Ensure the variable names exist within the entry and overrides
141141
for variable_name in formatter.format_variables:
142-
if variable_name not in variable_dict:
142+
# If the variable exists, but is sanitized...
143+
if (
144+
variable_name.endswith("_sanitized")
145+
and variable_name.removesuffix("_sanitized") in variable_dict
146+
):
147+
# Resolve just the non-sanitized version, then sanitize it
148+
variable_dict[variable_name] = sanitize_filename(
149+
StringFormatterValidator(
150+
name=self._name, value=f"{{{variable_name.removesuffix('_sanitized')}}}"
151+
).apply_formatter(variable_dict)
152+
)
153+
# If the variable doesn't exist, error
154+
elif variable_name not in variable_dict:
143155
available_fields = ", ".join(sorted(variable_dict.keys()))
144156
raise self._validation_exception(
145157
self._variable_not_found_error_msg_formatter.format(
@@ -153,25 +165,25 @@ def __apply_formatter(
153165
value=formatter.format_string.format(**OrderedDict(variable_dict)),
154166
)
155167

156-
def _apply_formatter(self, variable_dict: Dict[str, str], resolve_sanitized: bool = False):
168+
def apply_formatter(self, variable_dict: Dict[str, str]) -> str:
169+
"""
170+
Calls `format` on the format string using the variable_dict as input kwargs
171+
172+
Parameters
173+
----------
174+
variable_dict
175+
kwargs to pass to the format string
176+
177+
Returns
178+
-------
179+
Format string formatted
180+
"""
157181
formatter = self
158182
recursion_depth = 0
159183
max_depth = self._max_format_recursion
160184

161-
if resolve_sanitized:
162-
for format_variable in formatter.format_variables:
163-
# Must resolve the sanitized variable completely
164-
if format_variable.endswith("_sanitized"):
165-
# pylint: disable=protected-access
166-
variable_dict[format_variable] = sanitize_filename(
167-
StringFormatterValidator(
168-
name=self._name, value=f"{{{format_variable}}}"
169-
)._apply_formatter(variable_dict, resolve_sanitized=False)
170-
)
171-
# pylint: enable=protected-access
172-
173185
while formatter.format_variables and recursion_depth < max_depth:
174-
formatter = self.__apply_formatter(formatter=formatter, variable_dict=variable_dict)
186+
formatter = self._apply_formatter(formatter=formatter, variable_dict=variable_dict)
175187
recursion_depth += 1
176188

177189
if formatter.format_variables:
@@ -184,21 +196,6 @@ def _apply_formatter(self, variable_dict: Dict[str, str], resolve_sanitized: boo
184196

185197
return formatter.format_string
186198

187-
def apply_formatter(self, variable_dict: Dict[str, str]) -> str:
188-
"""
189-
Calls `format` on the format string using the variable_dict as input kwargs
190-
191-
Parameters
192-
----------
193-
variable_dict
194-
kwargs to pass to the format string
195-
196-
Returns
197-
-------
198-
Format string formatted
199-
"""
200-
return self._apply_formatter(variable_dict=variable_dict, resolve_sanitized=True)
201-
202199

203200
# pylint: disable=line-too-long
204201
class OverridesStringFormatterValidator(StringFormatterValidator):
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
".ytdl-sub-chapters_from_comments-download-archive.json": "122723ce8d257eebb05178daa26141f6",
33
"JMC/JMC - Move 78 - Automated Improvisation [Full Album]-thumb.jpg": "c12e6a6f242680d1096a1a99d74a62c6",
4-
"JMC/JMC - Move 78 - Automated Improvisation [Full Album].info.json": "6654b2b5bbf4e7dfb51f2c5e3138df63",
5-
"JMC/JMC - Move 78 - Automated Improvisation [Full Album].mp4": "5bd2291db1ee7848ff5d8ed0fdb98782",
4+
"JMC/JMC - Move 78 - Automated Improvisation [Full Album].info.json": "6fece242a390ce0756f39aab731f47f4",
5+
"JMC/JMC - Move 78 - Automated Improvisation [Full Album].mp4": "40a74798dddf486a656c761516eb0528",
66
"JMC/JMC - Move 78 - Automated Improvisation [Full Album].nfo": "7a65b184d24c68fc0ec5380432250f5b"
77
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
".ytdl-sub-file_convert_test-download-archive.json": "65aa49c7345f9fc201e42ddc4a96b19b",
33
"Beyond The Guitar/Beyond The Guitar - When you hear Hugh Jackman is returning as Wolverine in Deadpool 3-thumb.jpg": "662fcaadf6e80d63591bac19a5fdffb0",
4-
"Beyond The Guitar/Beyond The Guitar - When you hear Hugh Jackman is returning as Wolverine in Deadpool 3.info.json": "bdc0ecb04fb478ecf787ddbc64325a2b",
4+
"Beyond The Guitar/Beyond The Guitar - When you hear Hugh Jackman is returning as Wolverine in Deadpool 3.info.json": "90d8f639520d8295e009c41f328180a0",
55
"Beyond The Guitar/Beyond The Guitar - When you hear Hugh Jackman is returning as Wolverine in Deadpool 3.mp4": "390177bcc076e309d1534b8bb5afdcc7",
66
"Beyond The Guitar/Beyond The Guitar - When you hear Hugh Jackman is returning as Wolverine in Deadpool 3.nfo": "cacf09ab38f9b3085da9c5af516cf22a"
77
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
".ytdl-sub-file_convert_test-download-archive.json": "74813dccf4e9732e49f5dc3c2d66f3be",
33
"Beyond The Guitar/Beyond The Guitar - When you hear Hugh Jackman is returning as Wolverine in Deadpool 3-thumb.jpg": "662fcaadf6e80d63591bac19a5fdffb0",
4-
"Beyond The Guitar/Beyond The Guitar - When you hear Hugh Jackman is returning as Wolverine in Deadpool 3.info.json": "3022131504a9df5d2fce266fada1ee3b",
4+
"Beyond The Guitar/Beyond The Guitar - When you hear Hugh Jackman is returning as Wolverine in Deadpool 3.info.json": "bd0925c1975a669ec298c810719b9c43",
55
"Beyond The Guitar/Beyond The Guitar - When you hear Hugh Jackman is returning as Wolverine in Deadpool 3.mkv": "b5f248b560f89f3f2a83fcdcd197d486",
66
"Beyond The Guitar/Beyond The Guitar - When you hear Hugh Jackman is returning as Wolverine in Deadpool 3.nfo": "cacf09ab38f9b3085da9c5af516cf22a"
77
}

tests/resources/expected_downloads_summaries/plugins/split_by_chapters_video.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
2-
".ytdl-sub-split_by_chapters_video-download-archive.json": "5e7a31ec4a73e71696f8f3ba9eab9303",
2+
".ytdl-sub-split_by_chapters_video-download-archive.json": "c3fb0b4f31caaa10ac7954ea93da33c4",
33
"Proved Records/[2017] Alfa Mist - Nocturne [Full Album]/01 - 01. Intro (Feat. Racheal Ofori & Barney Artist).mp3": "29d09da874133ce5c5f7459c2fa6cd85",
44
"Proved Records/[2017] Alfa Mist - Nocturne [Full Album]/02 - 02. Answers (Feat. Rick David & Kaya Thomas - Dyke).mp3": "d5432e6a4f7af9810b0e7c8eebe4898a",
55
"Proved Records/[2017] Alfa Mist - Nocturne [Full Album]/03 - 03. Blaze (Feat. Kaya Thomas - Dyke).mp3": "cf03da6688a73373f9295dc595156e11",
66
"Proved Records/[2017] Alfa Mist - Nocturne [Full Album]/04 - 04. What If (Interlude).mp3": "b7b943b6f3395c05433b8532364d63d6",
77
"Proved Records/[2017] Alfa Mist - Nocturne [Full Album]/05 - 05. No Peace (Feat. Tom Misch).mp3": "0d9719268900d4abcd8c0f51ad3af92c",
88
"Proved Records/[2017] Alfa Mist - Nocturne [Full Album]/06 - 06. Closer (Feat. Lester Duval).mp3": "bbd9ec616a0f7d3c5d13c04bb118681e",
9-
"Proved Records/[2017] Alfa Mist - Nocturne [Full Album]/07 - 07. Delusions: Rumination (Interlude) (Feat. Racheal Ofori).mp3": "2e59ecdc0f8050bcf190a7898d7ae968",
9+
"Proved Records/[2017] Alfa Mist - Nocturne [Full Album]/07 - 07. Delusions Rumination (Interlude) (Feat. Racheal Ofori).mp3": "2e59ecdc0f8050bcf190a7898d7ae968",
1010
"Proved Records/[2017] Alfa Mist - Nocturne [Full Album]/08 - 08. Dreams (Feat. Carmody).mp3": "e58966f3326b876f0ab97459b681f76f",
1111
"Proved Records/[2017] Alfa Mist - Nocturne [Full Album]/09 - 09. Dreaming (Interlude) (Feat. Racheal Ofori).mp3": "d6939215b73457fce4e026f8c9b57ecc",
1212
"Proved Records/[2017] Alfa Mist - Nocturne [Full Album]/10 - 10. Hopeful (Feat. Jordan Rakei).mp3": "82d0e7d8070fd15d71c2e11c0285d426",
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
".ytdl-sub-split_by_chapters_with_regex_video-download-archive.json": "ed212171889707bf65462878248fc0b8",
3-
"Project Zombie/[2010] Oblivion Mod \"Falcor\" p.1/01 - Oblivion Mod \"Falcor\" p.1.mp3": "a3c01f164eeca4541aeed49264d2fc8c",
4-
"Project Zombie/[2010] Oblivion Mod \"Falcor\" p.1/folder.jpg": "fb95b510681676e81c321171fc23143e"
2+
".ytdl-sub-split_by_chapters_with_regex_video-download-archive.json": "4008e43668447f1a3a6a55520a6ff475",
3+
"Project Zombie/[2010] Oblivion Mod Falcor p.1/01 - Oblivion Mod Falcor p.1.mp3": "a3c01f164eeca4541aeed49264d2fc8c",
4+
"Project Zombie/[2010] Oblivion Mod Falcor p.1/folder.jpg": "fb95b510681676e81c321171fc23143e"
55
}

tests/resources/expected_downloads_summaries/plugins/split_by_chapters_with_regex_video.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
2-
".ytdl-sub-split_by_chapters_with_regex_video-download-archive.json": "cb82ae5ed9d7a41aea15446254c93738",
2+
".ytdl-sub-split_by_chapters_with_regex_video-download-archive.json": "9798e8289742586d0efd295a97c6c906",
33
"Alfa Mist/[2017] Nocturne/01 - Intro (Feat. Racheal Ofori & Barney Artist).mp3": "7be57c4dde9ba2c3fa72e9cc65b0f586",
44
"Alfa Mist/[2017] Nocturne/02 - Answers (Feat. Rick David & Kaya Thomas - Dyke).mp3": "5ee032da9965c51913fcfa0319d061bd",
55
"Alfa Mist/[2017] Nocturne/03 - Blaze (Feat. Kaya Thomas - Dyke).mp3": "82c1f35bdccfb4ec146f33661ac94d6b",
66
"Alfa Mist/[2017] Nocturne/04 - What If (Interlude).mp3": "040b38c249e478d8832dcea8bfeca17f",
77
"Alfa Mist/[2017] Nocturne/05 - No Peace (Feat. Tom Misch).mp3": "06f7e57fecdc7b4d2e37c7652791ce19",
88
"Alfa Mist/[2017] Nocturne/06 - Closer (Feat. Lester Duval).mp3": "91a03449c33bf9dcff5a9654a8525626",
9-
"Alfa Mist/[2017] Nocturne/07 - Delusions: Rumination (Interlude) (Feat. Racheal Ofori).mp3": "54c26621b8d4e74f37217c836479a077",
9+
"Alfa Mist/[2017] Nocturne/07 - Delusions Rumination (Interlude) (Feat. Racheal Ofori).mp3": "54c26621b8d4e74f37217c836479a077",
1010
"Alfa Mist/[2017] Nocturne/08 - Dreams (Feat. Carmody).mp3": "2704327ac5998086e77a77da164e2afd",
1111
"Alfa Mist/[2017] Nocturne/09 - Dreaming (Interlude) (Feat. Racheal Ofori).mp3": "75b8a26d3099aa2d9ba488b33c4eb1e7",
1212
"Alfa Mist/[2017] Nocturne/10 - Hopeful (Feat. Jordan Rakei).mp3": "0bf0979c99c55ef986efaba55c0dc858",
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
".ytdl-sub-single_song_test-download-archive.json": "22c1431e35033d777a674c4802bcc786",
3-
"YouTube/[2019] YouTube Rewind 2019: For the Record | #YouTubeRewind/01 - YouTube Rewind 2019: For the Record | #YouTubeRewind.mp3": "7affc0ecf01f36de9cee1a7aafd776eb",
4-
"YouTube/[2019] YouTube Rewind 2019: For the Record | #YouTubeRewind/folder.jpg": "50ee47c80f679029f5d3503bb91b045a"
2+
".ytdl-sub-single_song_test-download-archive.json": "c8ff22ec3304c9f8dab18cedaed4e8b4",
3+
"YouTube/[2019] YouTube Rewind 2019 For the Record #YouTubeRewind/01 - YouTube Rewind 2019 For the Record #YouTubeRewind.mp3": "7affc0ecf01f36de9cee1a7aafd776eb",
4+
"YouTube/[2019] YouTube Rewind 2019 For the Record #YouTubeRewind/folder.jpg": "50ee47c80f679029f5d3503bb91b045a"
55
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
".ytdl-sub-sponsorblock_with_embedded_subs_test-download-archive.json": "40abc64a8fe93a10406bff1548a2cbe2",
33
"JMC/JMC - This GPU SLIDES into this Case! - Silverstone SUGO 16 ITX Case-thumb.jpg": "b5353a824a4800cc26f884e3025ed969",
4-
"JMC/JMC - This GPU SLIDES into this Case! - Silverstone SUGO 16 ITX Case.info.json": "4304c960965fa4bcf91a3b0f0d97ce62",
5-
"JMC/JMC - This GPU SLIDES into this Case! - Silverstone SUGO 16 ITX Case.mp4": "8ed30bf3716a5f86eff0de78582cff2e",
4+
"JMC/JMC - This GPU SLIDES into this Case! - Silverstone SUGO 16 ITX Case.info.json": "e0063c9893bdbb08ac8766c67952be44",
5+
"JMC/JMC - This GPU SLIDES into this Case! - Silverstone SUGO 16 ITX Case.mp4": "d0d1ac72d6a968bb4fe77e79abc784c7",
66
"JMC/JMC - This GPU SLIDES into this Case! - Silverstone SUGO 16 ITX Case.nfo": "b9bd35e4f260c728774d8dd31f83637c"
77
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
".ytdl-sub-subtitles_embedded_test-download-archive.json": "1aa35c1d2663ac721f33f8374c00af1a",
33
"JMC/JMC - YouTube Rewind 2019: For the Record | #YouTubeRewind-thumb.jpg": "50ee47c80f679029f5d3503bb91b045a",
4-
"JMC/JMC - YouTube Rewind 2019: For the Record | #YouTubeRewind.info.json": "c7a301a9429360ad4b82c280142c9677",
4+
"JMC/JMC - YouTube Rewind 2019: For the Record | #YouTubeRewind.info.json": "4efbf3e5ff5ceb8589dab87f9934927f",
55
"JMC/JMC - YouTube Rewind 2019: For the Record | #YouTubeRewind.mp4": "1f1f91f85b162c20596a2413e704b809",
66
"JMC/JMC - YouTube Rewind 2019: For the Record | #YouTubeRewind.nfo": "c64964fab07574080e5da3242e3bfd48"
77
}

0 commit comments

Comments
 (0)