summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2021-04-22 20:07:02 (GMT)
committerGitHub <noreply@github.com>2021-04-22 20:07:02 (GMT)
commit400bd9a3858ea28ea264682b7f050c69638b1ff1 (patch)
tree17491855a2a2261b066e74ce2ae1f34af5dfdd7f
parentef63328b46fe7402794cde51008a47e79f37b153 (diff)
downloadcpython-400bd9a3858ea28ea264682b7f050c69638b1ff1.zip
cpython-400bd9a3858ea28ea264682b7f050c69638b1ff1.tar.gz
cpython-400bd9a3858ea28ea264682b7f050c69638b1ff1.tar.bz2
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 fe63a401a9b3ca1751b81b5d6ddb2beb7f3675c1) Co-authored-by: Steve Dower <steve.dower@python.org>
-rw-r--r--Misc/NEWS.d/next/Windows/2021-04-22-19-49-20.bpo-38822.jgdPmq.rst3
-rw-r--r--Modules/posixmodule.c23
2 files changed, 24 insertions, 2 deletions
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
index 0000000..072a969
--- /dev/null
+++ b/Misc/NEWS.d/next/Windows/2021-04-22-19-49-20.bpo-38822.jgdPmq.rst
@@ -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`.
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 0ef75fa..e821f1a 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -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;