Skip to content

Commit

Permalink
pythonGH-123599: Reject non-local authority in `pathlib.Path.from_uri…
Browse files Browse the repository at this point in the history
…()` on POSIX

Raise `ValueError` in `pathlib.Path.from_uri()` if the given `file:` URI
specifies a non-empty, non-`localhost` authority, and we're running on a
platform without support for UNC paths.
  • Loading branch information
barneygale committed Sep 3, 2024
1 parent 68fe575 commit 0cee0c4
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 3 deletions.
6 changes: 6 additions & 0 deletions Doc/library/pathlib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,12 @@ conforming to :rfc:`8089`.
:exc:`ValueError` is raised if the URI does not start with ``file:``, or
the parsed path isn't absolute.

On POSIX systems, :exc:`ValueError` is raised if the URI specifies a
non-local authority::

>>> Path.from_uri('file://server/share')
ValueError: URI is not local: 'file://server/share'

.. versionadded:: 3.13


Expand Down
3 changes: 3 additions & 0 deletions Lib/pathlib/_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -904,6 +904,9 @@ def from_uri(cls, uri):
elif path[:12] == '//localhost/':
# Remove 'localhost' authority
path = path[11:]
elif path[:2] == '//' and os.name != 'nt':
# UNC paths aren't supported on POSIX
raise ValueError(f"URI is not local: {uri!r}")
if path[:3] == '///' or (path[:1] == '/' and path[2:3] in ':|'):
# Remove slash before DOS device/UNC path
path = path[1:]
Expand Down
7 changes: 4 additions & 3 deletions Lib/test/test_pathlib/test_pathlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -1698,21 +1698,22 @@ def test_handling_bad_descriptor(self):
def test_from_uri_posix(self):
P = self.cls
self.assertEqual(P.from_uri('file:/foo/bar'), P('/foo/bar'))
self.assertEqual(P.from_uri('file://foo/bar'), P('//foo/bar'))
self.assertEqual(P.from_uri('file:///foo/bar'), P('/foo/bar'))
self.assertEqual(P.from_uri('file:////foo/bar'), P('//foo/bar'))
self.assertEqual(P.from_uri('file://localhost/foo/bar'), P('/foo/bar'))
self.assertEqual(P.from_uri('file://localhost//foo/bar'), P('//foo/bar'))
self.assertRaises(ValueError, P.from_uri, 'foo/bar')
self.assertRaises(ValueError, P.from_uri, '/foo/bar')
self.assertRaises(ValueError, P.from_uri, '//foo/bar')
self.assertRaises(ValueError, P.from_uri, 'file:foo/bar')
self.assertRaises(ValueError, P.from_uri, 'file://foo/bar')
self.assertRaises(ValueError, P.from_uri, 'http://foo/bar')

@needs_posix
def test_from_uri_pathname2url_posix(self):
P = self.cls
self.assertEqual(P.from_uri('file:' + pathname2url('/foo/bar')), P('/foo/bar'))
self.assertEqual(P.from_uri('file:' + pathname2url('//foo/bar')), P('//foo/bar'))
self.assertEqual(P.from_uri('file://' + pathname2url('/foo/bar')), P('/foo/bar'))
self.assertEqual(P.from_uri('file://' + pathname2url('//foo/bar')), P('//foo/bar'))

@needs_windows
def test_absolute_windows(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fix issue where :meth:`pathlib.Path.from_uri` accepted URIs with non-local
authorities on POSIX. This method now raises `ValueError` when given a URI
like ``file://server/share`` on a non-Windows system.

0 comments on commit 0cee0c4

Please sign in to comment.