aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Sawicki <contact@grub4k.xyz>2025-01-25 22:32:00 +0100
committerGitHub <noreply@github.com>2025-01-25 22:32:00 +0100
commitfc12e724a3b4988cfc467d2981887dde48c26b69 (patch)
tree559e53f0d0ac08d120923cdb092892ce6a34fd6c
parent61ae5dc34ac775d6c122575e21ef2153b1273a2b (diff)
[utils] `sanitize_path`: Fix some incorrect behavior (#11923)
Authored by: Grub4K
-rw-r--r--test/test_utils.py37
-rw-r--r--yt_dlp/utils/_utils.py9
2 files changed, 34 insertions, 12 deletions
diff --git a/test/test_utils.py b/test/test_utils.py
index b3de14198..8f81d0b1b 100644
--- a/test/test_utils.py
+++ b/test/test_utils.py
@@ -249,17 +249,36 @@ class TestUtil(unittest.TestCase):
self.assertEqual(sanitize_path('abc/def...'), 'abc\\def..#')
self.assertEqual(sanitize_path('abc.../def'), 'abc..#\\def')
self.assertEqual(sanitize_path('abc.../def...'), 'abc..#\\def..#')
-
- self.assertEqual(sanitize_path('../abc'), '..\\abc')
- self.assertEqual(sanitize_path('../../abc'), '..\\..\\abc')
- self.assertEqual(sanitize_path('./abc'), 'abc')
- self.assertEqual(sanitize_path('./../abc'), '..\\abc')
-
- self.assertEqual(sanitize_path('\\abc'), '\\abc')
- self.assertEqual(sanitize_path('C:abc'), 'C:abc')
- self.assertEqual(sanitize_path('C:abc\\..\\'), 'C:..')
self.assertEqual(sanitize_path('C:\\abc:%(title)s.%(ext)s'), 'C:\\abc#%(title)s.%(ext)s')
+ # Check with nt._path_normpath if available
+ try:
+ import nt
+
+ nt_path_normpath = getattr(nt, '_path_normpath', None)
+ except Exception:
+ nt_path_normpath = None
+
+ for test, expected in [
+ ('C:\\', 'C:\\'),
+ ('../abc', '..\\abc'),
+ ('../../abc', '..\\..\\abc'),
+ ('./abc', 'abc'),
+ ('./../abc', '..\\abc'),
+ ('\\abc', '\\abc'),
+ ('C:abc', 'C:abc'),
+ ('C:abc\\..\\', 'C:'),
+ ('C:abc\\..\\def\\..\\..\\', 'C:..'),
+ ('C:\\abc\\xyz///..\\def\\', 'C:\\abc\\def'),
+ ('abc/../', '.'),
+ ('./abc/../', '.'),
+ ]:
+ result = sanitize_path(test)
+ assert result == expected, f'{test} was incorrectly resolved'
+ assert result == sanitize_path(result), f'{test} changed after sanitizing again'
+ if nt_path_normpath:
+ assert result == nt_path_normpath(test), f'{test} does not match nt._path_normpath'
+
def test_sanitize_url(self):
self.assertEqual(sanitize_url('//foo.bar'), 'http://foo.bar')
self.assertEqual(sanitize_url('httpss://foo.bar'), 'https://foo.bar')
diff --git a/yt_dlp/utils/_utils.py b/yt_dlp/utils/_utils.py
index 699bf1e7f..17d8424c4 100644
--- a/yt_dlp/utils/_utils.py
+++ b/yt_dlp/utils/_utils.py
@@ -685,7 +685,8 @@ def _sanitize_path_parts(parts):
elif part == '..':
if sanitized_parts and sanitized_parts[-1] != '..':
sanitized_parts.pop()
- sanitized_parts.append('..')
+ else:
+ sanitized_parts.append('..')
continue
# Replace invalid segments with `#`
# - trailing dots and spaces (`asdf...` => `asdf..#`)
@@ -702,7 +703,8 @@ def sanitize_path(s, force=False):
if not force:
return s
root = '/' if s.startswith('/') else ''
- return root + '/'.join(_sanitize_path_parts(s.split('/')))
+ path = '/'.join(_sanitize_path_parts(s.split('/')))
+ return root + path if root or path else '.'
normed = s.replace('/', '\\')
@@ -721,7 +723,8 @@ def sanitize_path(s, force=False):
root = '\\' if normed[:1] == '\\' else ''
parts = normed.split('\\')
- return root + '\\'.join(_sanitize_path_parts(parts))
+ path = '\\'.join(_sanitize_path_parts(parts))
+ return root + path if root or path else '.'
def sanitize_url(url, *, scheme='http'):