Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 052e4f1

Browse files
committed
Issue #28075: Merge from 3.5
2 parents d508d00 + 0b4dc48 commit 052e4f1

3 files changed

Lines changed: 26 additions & 2 deletions

File tree

Lib/test/test_os.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,25 @@ def test_file_attributes(self):
460460
result.st_file_attributes & stat.FILE_ATTRIBUTE_DIRECTORY,
461461
stat.FILE_ATTRIBUTE_DIRECTORY)
462462

463+
@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
464+
def test_access_denied(self):
465+
# Default to FindFirstFile WIN32_FIND_DATA when access is
466+
# denied. See issue 28075.
467+
# os.environ['TEMP'] should be located on a volume that
468+
# supports file ACLs.
469+
fname = os.path.join(os.environ['TEMP'], self.fname)
470+
self.addCleanup(support.unlink, fname)
471+
create_file(fname, b'ABC')
472+
# Deny the right to [S]YNCHRONIZE on the file to
473+
# force CreateFile to fail with ERROR_ACCESS_DENIED.
474+
DETACHED_PROCESS = 8
475+
subprocess.check_call(
476+
['icacls.exe', fname, '/deny', 'Users:(S)'],
477+
creationflags=DETACHED_PROCESS
478+
)
479+
result = os.stat(fname)
480+
self.assertNotEqual(result.st_size, 0)
481+
463482

464483
class UtimeTests(unittest.TestCase):
465484
def setUp(self):

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ Core and Builtins
2727
Library
2828
-------
2929

30+
- Issue #28075: Check for ERROR_ACCESS_DENIED in Windows implementation of
31+
os.stat(). Patch by Eryk Sun.
32+
3033
- Issue #22493: Warning message emitted by using inline flags in the middle of
3134
regular expression now contains a (truncated) regex pattern.
3235
Patch by Tim Graham.

Modules/posixmodule.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1545,7 +1545,9 @@ win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
15451545
/* Either the target doesn't exist, or we don't have access to
15461546
get a handle to it. If the former, we need to return an error.
15471547
If the latter, we can use attributes_from_dir. */
1548-
if (GetLastError() != ERROR_SHARING_VIOLATION)
1548+
DWORD lastError = GetLastError();
1549+
if (lastError != ERROR_ACCESS_DENIED &&
1550+
lastError != ERROR_SHARING_VIOLATION)
15491551
return -1;
15501552
/* Could not get attributes on open file. Fall back to
15511553
reading the directory. */
@@ -1555,7 +1557,7 @@ win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
15551557
if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
15561558
if (traverse) {
15571559
/* Should traverse, but could not open reparse point handle */
1558-
SetLastError(ERROR_SHARING_VIOLATION);
1560+
SetLastError(lastError);
15591561
return -1;
15601562
}
15611563
}

0 commit comments

Comments
 (0)