]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] GH-120423: `pathname2url()`: handle forward slashes in Windows paths (GH-12659...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 12 Nov 2024 21:53:58 +0000 (22:53 +0100)
committerGitHub <noreply@github.com>
Tue, 12 Nov 2024 21:53:58 +0000 (21:53 +0000)
GH-120423: `pathname2url()`: handle forward slashes in Windows paths (GH-126593)

Adjust `urllib.request.pathname2url()` so that forward slashes in Windows
paths are handled identically to backward slashes.
(cherry picked from commit bf224bd7cef5d24eaff35945ebe7ffe14df7710f)

Co-authored-by: Barney Gale <barney.gale@gmail.com>
Lib/nturl2path.py
Lib/test/test_urllib.py
Misc/NEWS.d/next/Library/2024-11-08-17-05-10.gh-issue-120423.7rdLVV.rst [new file with mode: 0644]

index 2f9fec7893afd1b2e9770a38df398cdaa315b6d5..9ecabff21c33e144e3634e717ef706cf382f5b6f 100644 (file)
@@ -44,20 +44,21 @@ def pathname2url(p):
     import urllib.parse
     # First, clean up some special forms. We are going to sacrifice
     # the additional information anyway
-    if p[:4] == '\\\\?\\':
+    p = p.replace('\\', '/')
+    if p[:4] == '//?/':
         p = p[4:]
-        if p[:4].upper() == 'UNC\\':
-            p = '\\\\' + p[4:]
+        if p[:4].upper() == 'UNC/':
+            p = '//' + p[4:]
         elif p[1:2] != ':':
             raise OSError('Bad path: ' + p)
     if not ':' in p:
-        # No drive specifier, just convert slashes and quote the name
-        return urllib.parse.quote(p.replace('\\', '/'))
+        # No DOS drive specified, just quote the pathname
+        return urllib.parse.quote(p)
     comp = p.split(':', maxsplit=2)
     if len(comp) != 2 or len(comp[0]) > 1:
         error = 'Bad path: ' + p
         raise OSError(error)
 
     drive = urllib.parse.quote(comp[0].upper())
-    tail = urllib.parse.quote(comp[1].replace('\\', '/'))
+    tail = urllib.parse.quote(comp[1])
     return '///' + drive + ':' + tail
index 2b59fb617cbdda2e65abff614b9b1d5cd4c271ac..5433072bcda74153c6407819bfd263d01276c5f6 100644 (file)
@@ -1551,6 +1551,11 @@ class Pathname_Tests(unittest.TestCase):
         self.assertEqual(fn('\\\\some\\share\\'), '//some/share/')
         self.assertEqual(fn('\\\\some\\share\\a\\b.c'), '//some/share/a/b.c')
         self.assertEqual(fn('\\\\some\\share\\a\\b%#c\xe9'), '//some/share/a/b%25%23c%C3%A9')
+        # Alternate path separator
+        self.assertEqual(fn('C:/a/b.c'), '///C:/a/b.c')
+        self.assertEqual(fn('//some/share/a/b.c'), '//some/share/a/b.c')
+        self.assertEqual(fn('//?/C:/dir'), '///C:/dir')
+        self.assertEqual(fn('//?/unc/server/share/dir'), '//server/share/dir')
         # Round-tripping
         urls = ['///C:',
                 '///folder/test/',
diff --git a/Misc/NEWS.d/next/Library/2024-11-08-17-05-10.gh-issue-120423.7rdLVV.rst b/Misc/NEWS.d/next/Library/2024-11-08-17-05-10.gh-issue-120423.7rdLVV.rst
new file mode 100644 (file)
index 0000000..b475257
--- /dev/null
@@ -0,0 +1,2 @@
+Fix issue where :func:`urllib.request.pathname2url` mishandled Windows paths
+with embedded forward slashes.