diff options
author | Barney Gale <barney.gale@gmail.com> | 2021-04-28 15:50:17 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-28 15:50:17 (GMT) |
commit | baecfbd849dbf42360d3a84af6cc13160838f24d (patch) | |
tree | 5d82a6504cd2859197e1bcd81ceaecef035a6aad /Lib/test/test_ntpath.py | |
parent | 859577c24981d6b36960d309f99f7fc810fe75c2 (diff) | |
download | cpython-baecfbd849dbf42360d3a84af6cc13160838f24d.zip cpython-baecfbd849dbf42360d3a84af6cc13160838f24d.tar.gz cpython-baecfbd849dbf42360d3a84af6cc13160838f24d.tar.bz2 |
bpo-43757: Make pathlib use os.path.realpath() to resolve symlinks in a path (GH-25264)
Also adds a new "strict" argument to realpath() to avoid changing the default behaviour of pathlib while sharing the implementation.
Diffstat (limited to 'Lib/test/test_ntpath.py')
-rw-r--r-- | Lib/test/test_ntpath.py | 60 |
1 files changed, 58 insertions, 2 deletions
diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index f97aca5..661c59d 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -271,6 +271,17 @@ class TestNtpath(NtpathTestCase): @os_helper.skip_unless_symlink @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') + def test_realpath_strict(self): + # Bug #43757: raise FileNotFoundError in strict mode if we encounter + # a path that does not exist. + ABSTFN = ntpath.abspath(os_helper.TESTFN) + os.symlink(ABSTFN + "1", ABSTFN) + self.addCleanup(os_helper.unlink, ABSTFN) + self.assertRaises(FileNotFoundError, ntpath.realpath, ABSTFN, strict=True) + self.assertRaises(FileNotFoundError, ntpath.realpath, ABSTFN + "2", strict=True) + + @os_helper.skip_unless_symlink + @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') def test_realpath_relative(self): ABSTFN = ntpath.abspath(os_helper.TESTFN) open(ABSTFN, "wb").close() @@ -340,8 +351,9 @@ class TestNtpath(NtpathTestCase): @os_helper.skip_unless_symlink @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') def test_realpath_symlink_loops(self): - # Symlink loops are non-deterministic as to which path is returned, but - # it will always be the fully resolved path of one member of the cycle + # Symlink loops in non-strict mode are non-deterministic as to which + # path is returned, but it will always be the fully resolved path of + # one member of the cycle ABSTFN = ntpath.abspath(os_helper.TESTFN) self.addCleanup(os_helper.unlink, ABSTFN) self.addCleanup(os_helper.unlink, ABSTFN + "1") @@ -385,6 +397,50 @@ class TestNtpath(NtpathTestCase): @os_helper.skip_unless_symlink @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') + def test_realpath_symlink_loops_strict(self): + # Symlink loops raise OSError in strict mode + ABSTFN = ntpath.abspath(os_helper.TESTFN) + self.addCleanup(os_helper.unlink, ABSTFN) + self.addCleanup(os_helper.unlink, ABSTFN + "1") + self.addCleanup(os_helper.unlink, ABSTFN + "2") + self.addCleanup(os_helper.unlink, ABSTFN + "y") + self.addCleanup(os_helper.unlink, ABSTFN + "c") + self.addCleanup(os_helper.unlink, ABSTFN + "a") + + os.symlink(ABSTFN, ABSTFN) + self.assertRaises(OSError, ntpath.realpath, ABSTFN, strict=True) + + os.symlink(ABSTFN + "1", ABSTFN + "2") + os.symlink(ABSTFN + "2", ABSTFN + "1") + self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1", strict=True) + self.assertRaises(OSError, ntpath.realpath, ABSTFN + "2", strict=True) + self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1\\x", strict=True) + # Windows eliminates '..' components before resolving links, so the + # following call is not expected to raise. + self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..", strict=True), + ntpath.dirname(ABSTFN)) + self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1\\..\\x", strict=True) + os.symlink(ABSTFN + "x", ABSTFN + "y") + self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1\\..\\" + + ntpath.basename(ABSTFN) + "y", + strict=True) + self.assertRaises(OSError, ntpath.realpath, + ABSTFN + "1\\..\\" + ntpath.basename(ABSTFN) + "1", + strict=True) + + os.symlink(ntpath.basename(ABSTFN) + "a\\b", ABSTFN + "a") + self.assertRaises(OSError, ntpath.realpath, ABSTFN + "a", strict=True) + + os.symlink("..\\" + ntpath.basename(ntpath.dirname(ABSTFN)) + + "\\" + ntpath.basename(ABSTFN) + "c", ABSTFN + "c") + self.assertRaises(OSError, ntpath.realpath, ABSTFN + "c", strict=True) + + # Test using relative path as well. + self.assertRaises(OSError, ntpath.realpath, ntpath.basename(ABSTFN), + strict=True) + + @os_helper.skip_unless_symlink + @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') def test_realpath_symlink_prefix(self): ABSTFN = ntpath.abspath(os_helper.TESTFN) self.addCleanup(os_helper.unlink, ABSTFN + "3") |