Skip to content

Commit

Permalink
pythonGH-126205: Fix conversion of UNC paths to file URIs (pythonGH-1…
Browse files Browse the repository at this point in the history
…26208)

File URIs for Windows UNC paths should begin with two slashes, not four.
(cherry picked from commit 951cb2c)

Co-authored-by: Barney Gale <[email protected]>
  • Loading branch information
barneygale authored and miss-islington committed Oct 31, 2024
1 parent 8004238 commit 1e81eb8
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 13 deletions.
7 changes: 1 addition & 6 deletions Lib/nturl2path.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,11 @@ def pathname2url(p):
if p[:4] == '\\\\?\\':
p = p[4:]
if p[:4].upper() == 'UNC\\':
p = '\\' + p[4:]
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
if p[:2] == '\\\\':
# path is something like \\host\path\on\remote\host
# convert this to ////host/path/on/remote/host
# (notice doubling of slashes at the start of the path)
p = '\\\\' + p
components = p.split('\\')
return urllib.parse.quote('/'.join(components))
comp = p.split(':', maxsplit=2)
Expand Down
14 changes: 7 additions & 7 deletions Lib/test/test_urllib.py
Original file line number Diff line number Diff line change
Expand Up @@ -1524,7 +1524,7 @@ def test_pathname2url_win(self):
# Test special prefixes are correctly handled in pathname2url()
fn = urllib.request.pathname2url
self.assertEqual(fn('\\\\?\\C:\\dir'), '///C:/dir')
self.assertEqual(fn('\\\\?\\unc\\server\\share\\dir'), '/server/share/dir')
self.assertEqual(fn('\\\\?\\unc\\server\\share\\dir'), '//server/share/dir')
self.assertEqual(fn("C:"), '///C:')
self.assertEqual(fn("C:\\"), '///C:')
self.assertEqual(fn('C:\\a\\b.c'), '///C:/a/b.c')
Expand All @@ -1535,14 +1535,14 @@ def test_pathname2url_win(self):
self.assertRaises(IOError, fn, "XX:\\")
# No drive letter
self.assertEqual(fn("\\folder\\test\\"), '/folder/test/')
self.assertEqual(fn("\\\\folder\\test\\"), '////folder/test/')
self.assertEqual(fn("\\\\\\folder\\test\\"), '/////folder/test/')
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')
self.assertEqual(fn("\\\\folder\\test\\"), '//folder/test/')
self.assertEqual(fn("\\\\\\folder\\test\\"), '///folder/test/')
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')
# Round-tripping
urls = ['///C:',
'/////folder/test/',
'///folder/test/',
'///C:/foo/bar/spam.foo']
for url in urls:
self.assertEqual(fn(urllib.request.url2pathname(url)), url)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix issue where :func:`urllib.request.pathname2url` generated URLs beginning
with four slashes (rather than two) when given a Windows UNC path.

0 comments on commit 1e81eb8

Please sign in to comment.