Commit 38485592 authored by Berker Peksag's avatar Berker Peksag

Issue #28075: Check for ERROR_ACCESS_DENIED in Windows implementation of os.stat()

Patch by Eryk Sun.
parent bdde7f36
......@@ -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):
......
......@@ -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.
......
......@@ -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;
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment