]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-38822: Fixed os.stat failing on inaccessible directories. (GH-25527)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Thu, 22 Apr 2021 20:07:02 +0000 (13:07 -0700)
committerGitHub <noreply@github.com>
Thu, 22 Apr 2021 20:07:02 +0000 (13:07 -0700)
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 fe63a401a9b3ca1751b81b5d6ddb2beb7f3675c1)

Co-authored-by: Steve Dower <steve.dower@python.org>
Misc/NEWS.d/next/Windows/2021-04-22-19-49-20.bpo-38822.jgdPmq.rst [new file with mode: 0644]
Modules/posixmodule.c

diff --git a/Misc/NEWS.d/next/Windows/2021-04-22-19-49-20.bpo-38822.jgdPmq.rst b/Misc/NEWS.d/next/Windows/2021-04-22-19-49-20.bpo-38822.jgdPmq.rst
new file mode 100644 (file)
index 0000000..072a969
--- /dev/null
@@ -0,0 +1,3 @@
+Fixed :func:`os.stat` failing on inaccessible directories with a trailing
+slash, rather than falling back to the parent directory's metadata. This
+implicitly affected :func:`os.path.exists` and :func:`os.path.isdir`.
index 0ef75fa4486ff661278e3f0d28c8b85203cbb83f..e821f1a59bde8aad808cce057c38a29dd2884a47 100644 (file)
@@ -1651,9 +1651,28 @@ attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *re
 {
     HANDLE hFindFile;
     WIN32_FIND_DATAW FileData;
-    hFindFile = FindFirstFileW(pszFile, &FileData);
-    if (hFindFile == INVALID_HANDLE_VALUE)
+    LPCWSTR filename = pszFile;
+    size_t n = wcslen(pszFile);
+    if (n && (pszFile[n - 1] == L'\\' || pszFile[n - 1] == L'/')) {
+        // cannot use PyMem_Malloc here because we do not hold the GIL
+        filename = (LPCWSTR)malloc((n + 1) * sizeof(filename[0]));
+        wcsncpy_s((LPWSTR)filename, n + 1, pszFile, n);
+        while (--n > 0 && (filename[n] == L'\\' || filename[n] == L'/')) {
+            ((LPWSTR)filename)[n] = L'\0';
+        }
+        if (!n || filename[n] == L':') {
+            // Nothing left te query
+            free((void *)filename);
+            return FALSE;
+        }
+    }
+    hFindFile = FindFirstFileW(filename, &FileData);
+    if (pszFile != filename) {
+        free((void *)filename);
+    }
+    if (hFindFile == INVALID_HANDLE_VALUE) {
         return FALSE;
+    }
     FindClose(hFindFile);
     find_data_to_file_info(&FileData, info, reparse_tag);
     return TRUE;