summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
authorBarney Gale <barney.gale@gmail.com>2024-11-13 22:59:32 (GMT)
committerGitHub <noreply@github.com>2024-11-13 22:59:32 (GMT)
commitfd4b5453df74e249987553b12c14ad75fafa4991 (patch)
treebffc6a81cdd6a05b097468aedf6b9206944d61eb /Lib/test
parentc695e37a3f95c225ee08d1e882d23fa200b5ec34 (diff)
downloadcpython-fd4b5453df74e249987553b12c14ad75fafa4991.zip
cpython-fd4b5453df74e249987553b12c14ad75fafa4991.tar.gz
cpython-fd4b5453df74e249987553b12c14ad75fafa4991.tar.bz2
GH-118289: Fix handling of non-directories in `posixpath.realpath()` (#120127)
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.
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/test_posixpath.py59
1 files changed, 59 insertions, 0 deletions
diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py
index ca5cf42..b39255eb 100644
--- a/Lib/test/test_posixpath.py
+++ b/Lib/test/test_posixpath.py
@@ -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: