mirror of
https://github.com/python/cpython.git
synced 2025-07-31 07:04:42 +00:00
[3.13] GH-118289: Fix handling of non-directories in posixpath.realpath()
(GH-120127) (#126815)
In strict mode, raise `NotADirectoryError` if we encounter a non-directory
while we still have path parts left to process.
We use a `part_count` variable rather than `len(rest)` because the `rest`
stack also contains markers for unresolved symlinks.
(cherry picked from commit fd4b5453df
)
This commit is contained in:
parent
ad1b23bf29
commit
b66728da05
3 changed files with 76 additions and 4 deletions
|
@ -695,6 +695,65 @@ class PosixPathTest(unittest.TestCase):
|
|||
os.chmod(ABSTFN, 0o755, follow_symlinks=False)
|
||||
os.unlink(ABSTFN)
|
||||
|
||||
@skip_if_ABSTFN_contains_backslash
|
||||
def test_realpath_nonterminal_file(self):
|
||||
try:
|
||||
with open(ABSTFN, 'w') as f:
|
||||
f.write('test_posixpath wuz ere')
|
||||
self.assertEqual(realpath(ABSTFN, strict=False), ABSTFN)
|
||||
self.assertEqual(realpath(ABSTFN, strict=True), ABSTFN)
|
||||
self.assertEqual(realpath(ABSTFN + "/", strict=False), ABSTFN)
|
||||
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/", strict=True)
|
||||
self.assertEqual(realpath(ABSTFN + "/.", strict=False), ABSTFN)
|
||||
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.", strict=True)
|
||||
self.assertEqual(realpath(ABSTFN + "/..", strict=False), dirname(ABSTFN))
|
||||
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..", strict=True)
|
||||
self.assertEqual(realpath(ABSTFN + "/subdir", strict=False), ABSTFN + "/subdir")
|
||||
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir", strict=True)
|
||||
finally:
|
||||
os_helper.unlink(ABSTFN)
|
||||
|
||||
@os_helper.skip_unless_symlink
|
||||
@skip_if_ABSTFN_contains_backslash
|
||||
def test_realpath_nonterminal_symlink_to_file(self):
|
||||
try:
|
||||
with open(ABSTFN + "1", 'w') as f:
|
||||
f.write('test_posixpath wuz ere')
|
||||
os.symlink(ABSTFN + "1", ABSTFN)
|
||||
self.assertEqual(realpath(ABSTFN, strict=False), ABSTFN + "1")
|
||||
self.assertEqual(realpath(ABSTFN, strict=True), ABSTFN + "1")
|
||||
self.assertEqual(realpath(ABSTFN + "/", strict=False), ABSTFN + "1")
|
||||
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/", strict=True)
|
||||
self.assertEqual(realpath(ABSTFN + "/.", strict=False), ABSTFN + "1")
|
||||
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.", strict=True)
|
||||
self.assertEqual(realpath(ABSTFN + "/..", strict=False), dirname(ABSTFN))
|
||||
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..", strict=True)
|
||||
self.assertEqual(realpath(ABSTFN + "/subdir", strict=False), ABSTFN + "1/subdir")
|
||||
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir", strict=True)
|
||||
finally:
|
||||
os_helper.unlink(ABSTFN)
|
||||
|
||||
@os_helper.skip_unless_symlink
|
||||
@skip_if_ABSTFN_contains_backslash
|
||||
def test_realpath_nonterminal_symlink_to_symlinks_to_file(self):
|
||||
try:
|
||||
with open(ABSTFN + "2", 'w') as f:
|
||||
f.write('test_posixpath wuz ere')
|
||||
os.symlink(ABSTFN + "2", ABSTFN + "1")
|
||||
os.symlink(ABSTFN + "1", ABSTFN)
|
||||
self.assertEqual(realpath(ABSTFN, strict=False), ABSTFN + "2")
|
||||
self.assertEqual(realpath(ABSTFN, strict=True), ABSTFN + "2")
|
||||
self.assertEqual(realpath(ABSTFN + "/", strict=False), ABSTFN + "2")
|
||||
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/", strict=True)
|
||||
self.assertEqual(realpath(ABSTFN + "/.", strict=False), ABSTFN + "2")
|
||||
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.", strict=True)
|
||||
self.assertEqual(realpath(ABSTFN + "/..", strict=False), dirname(ABSTFN))
|
||||
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..", strict=True)
|
||||
self.assertEqual(realpath(ABSTFN + "/subdir", strict=False), ABSTFN + "2/subdir")
|
||||
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir", strict=True)
|
||||
finally:
|
||||
os_helper.unlink(ABSTFN)
|
||||
|
||||
def test_relpath(self):
|
||||
(real_getcwd, os.getcwd) = (os.getcwd, lambda: r"/home/user/bar")
|
||||
try:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue