[Python-checkins] cpython (2.7): # 2466: ismount now recognizes mount points user can't access.

r.david.murray python-checkins at python.org
Tue Aug 23 12:30:46 EDT 2016


https://hg.python.org/cpython/rev/75111791110b
changeset:   102858:75111791110b
branch:      2.7
parent:      102826:370bbeba21b3
user:        R David Murray <rdmurray at bitdance.com>
date:        Tue Aug 23 12:30:28 2016 -0400
summary:
  # 2466: ismount now recognizes mount points user can't access.

Patch by Robin Roth, backport by Xiang Zhang.

files:
  Lib/posixpath.py           |   2 +-
  Lib/test/test_posixpath.py |  66 +++++++++++++++++++++++++-
  Misc/ACKS                  |   1 +
  Misc/NEWS                  |   3 +
  4 files changed, 70 insertions(+), 2 deletions(-)


diff --git a/Lib/posixpath.py b/Lib/posixpath.py
--- a/Lib/posixpath.py
+++ b/Lib/posixpath.py
@@ -186,7 +186,7 @@
         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
--- 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 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 @@
             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 @@
     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
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1186,6 +1186,7 @@
 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
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -33,6 +33,9 @@
 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.

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list