Skip to content

Commit 8e7cebb

Browse files
bpo-38822: Fixed os.stat failing on inaccessible directories. (GH-25527)
It would just fail if the path was inaccessible and had a trailing slash. It should fall back to the parent directory's metadata. (cherry picked from commit fe63a40) Co-authored-by: Steve Dower <[email protected]>
1 parent 87a392d commit 8e7cebb

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fixed :func:`os.stat` failing on inaccessible directories with a trailing
2+
slash, rather than falling back to the parent directory's metadata. This
3+
implicitly affected :func:`os.path.exists` and :func:`os.path.isdir`.

Modules/posixmodule.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,9 +1799,28 @@ attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *re
17991799
{
18001800
HANDLE hFindFile;
18011801
WIN32_FIND_DATAW FileData;
1802-
hFindFile = FindFirstFileW(pszFile, &FileData);
1803-
if (hFindFile == INVALID_HANDLE_VALUE)
1802+
LPCWSTR filename = pszFile;
1803+
size_t n = wcslen(pszFile);
1804+
if (n && (pszFile[n - 1] == L'\\' || pszFile[n - 1] == L'/')) {
1805+
// cannot use PyMem_Malloc here because we do not hold the GIL
1806+
filename = (LPCWSTR)malloc((n + 1) * sizeof(filename[0]));
1807+
wcsncpy_s((LPWSTR)filename, n + 1, pszFile, n);
1808+
while (--n > 0 && (filename[n] == L'\\' || filename[n] == L'/')) {
1809+
((LPWSTR)filename)[n] = L'\0';
1810+
}
1811+
if (!n || filename[n] == L':') {
1812+
// Nothing left te query
1813+
free((void *)filename);
1814+
return FALSE;
1815+
}
1816+
}
1817+
hFindFile = FindFirstFileW(filename, &FileData);
1818+
if (pszFile != filename) {
1819+
free((void *)filename);
1820+
}
1821+
if (hFindFile == INVALID_HANDLE_VALUE) {
18041822
return FALSE;
1823+
}
18051824
FindClose(hFindFile);
18061825
find_data_to_file_info(&FileData, info, reparse_tag);
18071826
return TRUE;

0 commit comments

Comments
 (0)