]> granicus.if.org Git - python/commitdiff
Issue #28075: Check for ERROR_ACCESS_DENIED in Windows implementation of os.stat()
authorBerker Peksag <berker.peksag@gmail.com>
Sat, 17 Sep 2016 12:49:59 +0000 (15:49 +0300)
committerBerker Peksag <berker.peksag@gmail.com>
Sat, 17 Sep 2016 12:49:59 +0000 (15:49 +0300)
Patch by Eryk Sun.

Lib/test/test_os.py
Misc/NEWS
Modules/posixmodule.c

index a1046b7aa9653dcf6e6ef73b38f7029b8c047cd3..9189a82dea595fd85347a24b4153607df5850835 100644 (file)
@@ -432,6 +432,25 @@ class StatAttributeTests(unittest.TestCase):
             result.st_file_attributes & stat.FILE_ATTRIBUTE_DIRECTORY,
             stat.FILE_ATTRIBUTE_DIRECTORY)
 
+    @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
+    def test_access_denied(self):
+        # Default to FindFirstFile WIN32_FIND_DATA when access is
+        # denied. See issue 28075.
+        # os.environ['TEMP'] should be located on a volume that
+        # supports file ACLs.
+        fname = os.path.join(os.environ['TEMP'], self.fname)
+        self.addCleanup(support.unlink, fname)
+        create_file(fname, b'ABC')
+        # Deny the right to [S]YNCHRONIZE on the file to
+        # force CreateFile to fail with ERROR_ACCESS_DENIED.
+        DETACHED_PROCESS = 8
+        subprocess.check_call(
+            ['icacls.exe', fname, '/deny', 'Users:(S)'],
+            creationflags=DETACHED_PROCESS
+        )
+        result = os.stat(fname)
+        self.assertNotEqual(result.st_size, 0)
+
 
 class UtimeTests(unittest.TestCase):
     def setUp(self):
index f7fe181d295d509cbc0bd45bda574852ac12f8fb..8fbdd226340abd3799cadfc9b40cce5b0afcb574 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -71,6 +71,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #28075: Check for ERROR_ACCESS_DENIED in Windows implementation of
+  os.stat().  Patch by Eryk Sun.
+
 - Issue #25270: Prevent codecs.escape_encode() from raising SystemError when
   an empty bytestring is passed.
 
index f6f08bf9928e2ec28342a9fd798b592683368d7c..becf65489c164abe599020801fb02818dc440b27 100644 (file)
@@ -1515,7 +1515,9 @@ win32_xstat_impl(const char *path, struct _Py_stat_struct *result,
         /* Either the target doesn't exist, or we don't have access to
            get a handle to it. If the former, we need to return an error.
            If the latter, we can use attributes_from_dir. */
-        if (GetLastError() != ERROR_SHARING_VIOLATION)
+        DWORD lastError = GetLastError();
+        if (lastError != ERROR_ACCESS_DENIED &&
+            lastError != ERROR_SHARING_VIOLATION)
             return -1;
         /* Could not get attributes on open file. Fall back to
            reading the directory. */
@@ -1525,7 +1527,7 @@ win32_xstat_impl(const char *path, struct _Py_stat_struct *result,
         if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
             if (traverse) {
                 /* Should traverse, but could not open reparse point handle */
-                SetLastError(ERROR_SHARING_VIOLATION);
+                SetLastError(lastError);
                 return -1;
             }
         }