From: R David Murray Date: Tue, 23 Aug 2016 16:30:28 +0000 (-0400) Subject: # 2466: ismount now recognizes mount points user can't access. X-Git-Tag: v2.7.13rc1~200 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8578316697c27e5824cadb6f7a324f95445f6c1a;p=thirdparty%2FPython%2Fcpython.git # 2466: ismount now recognizes mount points user can't access. Patch by Robin Roth, backport by Xiang Zhang. --- diff --git a/Lib/posixpath.py b/Lib/posixpath.py index 8f928225e019..f5c2260f1e5f 100644 --- a/Lib/posixpath.py +++ b/Lib/posixpath.py @@ -186,7 +186,7 @@ def ismount(path): return False try: s1 = os.lstat(path) - s2 = os.lstat(join(path, '..')) + s2 = os.lstat(realpath(join(path, '..'))) except os.error: return False # It doesn't exist -- so not a mount point :-) dev1 = s1.st_dev diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py index fbb18fd22bd0..98bf0e041dd7 100644 --- a/Lib/test/test_posixpath.py +++ b/Lib/test/test_posixpath.py @@ -1,4 +1,5 @@ import unittest +from test import symlink_support from test import test_support, test_genericpath from test import test_support as support @@ -7,6 +8,11 @@ import os import sys from posixpath import realpath, abspath, dirname, basename +try: + import posix +except ImportError: + posix = None + # An absolute path to a temporary filename for testing. We can't rely on TESTFN # being an absolute path, so we need this. @@ -100,7 +106,7 @@ class PosixPathTest(unittest.TestCase): f.write("foo") f.close() self.assertIs(posixpath.islink(test_support.TESTFN + "1"), False) - if hasattr(os, "symlink"): + if symlink_support.can_symlink(): os.symlink(test_support.TESTFN + "1", test_support.TESTFN + "2") self.assertIs(posixpath.islink(test_support.TESTFN + "2"), True) os.remove(test_support.TESTFN + "1") @@ -196,6 +202,64 @@ class PosixPathTest(unittest.TestCase): def test_ismount(self): self.assertIs(posixpath.ismount("/"), True) + def test_ismount_non_existent(self): + # Non-existent mountpoint. + self.assertIs(posixpath.ismount(ABSTFN), False) + try: + os.mkdir(ABSTFN) + self.assertIs(posixpath.ismount(ABSTFN), False) + finally: + safe_rmdir(ABSTFN) + + @symlink_support.skip_unless_symlink + def test_ismount_symlinks(self): + # Symlinks are never mountpoints. + try: + os.symlink("/", ABSTFN) + self.assertIs(posixpath.ismount(ABSTFN), False) + finally: + os.unlink(ABSTFN) + + @unittest.skipIf(posix is None, "Test requires posix module") + def test_ismount_different_device(self): + # Simulate the path being on a different device from its parent by + # mocking out st_dev. + save_lstat = os.lstat + def fake_lstat(path): + st_ino = 0 + st_dev = 0 + if path == ABSTFN: + st_dev = 1 + st_ino = 1 + return posix.stat_result((0, st_ino, st_dev, 0, 0, 0, 0, 0, 0, 0)) + try: + os.lstat = fake_lstat + self.assertIs(posixpath.ismount(ABSTFN), True) + finally: + os.lstat = save_lstat + + @unittest.skipIf(posix is None, "Test requires posix module") + def test_ismount_directory_not_readable(self): + # issue #2466: Simulate ismount run on a directory that is not + # readable, which used to return False. + save_lstat = os.lstat + def fake_lstat(path): + st_ino = 0 + st_dev = 0 + if path.startswith(ABSTFN) and path != ABSTFN: + # ismount tries to read something inside the ABSTFN directory; + # simulate this being forbidden (no read permission). + raise OSError("Fake [Errno 13] Permission denied") + if path == ABSTFN: + st_dev = 1 + st_ino = 1 + return posix.stat_result((0, st_ino, st_dev, 0, 0, 0, 0, 0, 0, 0)) + try: + os.lstat = fake_lstat + self.assertIs(posixpath.ismount(ABSTFN), True) + finally: + os.lstat = save_lstat + def test_expanduser(self): self.assertEqual(posixpath.expanduser("foo"), "foo") with test_support.EnvironmentVarGuard() as env: diff --git a/Misc/ACKS b/Misc/ACKS index 0210a4cd3650..07e5724fe411 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1186,6 +1186,7 @@ Guido van Rossum Just van Rossum Hugo van Rossum Saskia van Rossum +Robin Roth Clement Rouault Donald Wallace Rouse II Liam Routt diff --git a/Misc/NEWS b/Misc/NEWS index 392e9e7f88a5..d7ba5893c859 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -33,6 +33,9 @@ Core and Builtins Library ------- +- Issue #2466: posixpath.ismount now correctly recognizes mount points which + the user does not have permission to access. + - Issue #27783: Fix possible usage of uninitialized memory in operator.methodcaller. - Issue #27774: Fix possible Py_DECREF on unowned object in _sre.