mirror of
https://github.com/python/cpython.git
synced 2025-11-03 03:22:27 +00:00
gh-82367: Use FindFirstFile Win32 API in ntpath.realpath() (GH-110298)
* Use `FindFirstFile` Win32 API to fix a bug where `ntpath.realpath()` breaks out of traversing a series of paths where a (handled) `ERROR_ACCESS_DENIED` or `ERROR_SHARING_VIOLATION` occurs. * Update docs to reflect that `ntpath.realpath()` eliminates MS-DOS style names.
This commit is contained in:
parent
2cb62c6437
commit
d33aa18f15
8 changed files with 132 additions and 8 deletions
40
Modules/clinic/posixmodule.c.h
generated
40
Modules/clinic/posixmodule.c.h
generated
|
|
@ -1848,6 +1848,40 @@ exit:
|
|||
|
||||
#if defined(MS_WINDOWS)
|
||||
|
||||
PyDoc_STRVAR(os__findfirstfile__doc__,
|
||||
"_findfirstfile($module, path, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"A function to get the real file name without accessing the file in Windows.");
|
||||
|
||||
#define OS__FINDFIRSTFILE_METHODDEF \
|
||||
{"_findfirstfile", (PyCFunction)os__findfirstfile, METH_O, os__findfirstfile__doc__},
|
||||
|
||||
static PyObject *
|
||||
os__findfirstfile_impl(PyObject *module, path_t *path);
|
||||
|
||||
static PyObject *
|
||||
os__findfirstfile(PyObject *module, PyObject *arg)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
path_t path = PATH_T_INITIALIZE("_findfirstfile", "path", 0, 0);
|
||||
|
||||
if (!path_converter(arg, &path)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = os__findfirstfile_impl(module, &path);
|
||||
|
||||
exit:
|
||||
/* Cleanup for path */
|
||||
path_cleanup(&path);
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
#endif /* defined(MS_WINDOWS) */
|
||||
|
||||
#if defined(MS_WINDOWS)
|
||||
|
||||
PyDoc_STRVAR(os__getvolumepathname__doc__,
|
||||
"_getvolumepathname($module, /, path)\n"
|
||||
"--\n"
|
||||
|
|
@ -11451,6 +11485,10 @@ exit:
|
|||
#define OS__GETFINALPATHNAME_METHODDEF
|
||||
#endif /* !defined(OS__GETFINALPATHNAME_METHODDEF) */
|
||||
|
||||
#ifndef OS__FINDFIRSTFILE_METHODDEF
|
||||
#define OS__FINDFIRSTFILE_METHODDEF
|
||||
#endif /* !defined(OS__FINDFIRSTFILE_METHODDEF) */
|
||||
|
||||
#ifndef OS__GETVOLUMEPATHNAME_METHODDEF
|
||||
#define OS__GETVOLUMEPATHNAME_METHODDEF
|
||||
#endif /* !defined(OS__GETVOLUMEPATHNAME_METHODDEF) */
|
||||
|
|
@ -11986,4 +12024,4 @@ exit:
|
|||
#ifndef OS_WAITSTATUS_TO_EXITCODE_METHODDEF
|
||||
#define OS_WAITSTATUS_TO_EXITCODE_METHODDEF
|
||||
#endif /* !defined(OS_WAITSTATUS_TO_EXITCODE_METHODDEF) */
|
||||
/*[clinic end generated code: output=8b60de6ddb925bc3 input=a9049054013a1b77]*/
|
||||
/*[clinic end generated code: output=a36904281a8a7507 input=a9049054013a1b77]*/
|
||||
|
|
|
|||
|
|
@ -4809,6 +4809,37 @@ cleanup:
|
|||
return result;
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
os._findfirstfile
|
||||
path: path_t
|
||||
/
|
||||
A function to get the real file name without accessing the file in Windows.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
os__findfirstfile_impl(PyObject *module, path_t *path)
|
||||
/*[clinic end generated code: output=106dd3f0779c83dd input=0734dff70f60e1a8]*/
|
||||
{
|
||||
PyObject *result;
|
||||
HANDLE hFindFile;
|
||||
WIN32_FIND_DATAW wFileData;
|
||||
WCHAR *wRealFileName;
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
hFindFile = FindFirstFileW(path->wide, &wFileData);
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
if (hFindFile == INVALID_HANDLE_VALUE) {
|
||||
path_error(path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wRealFileName = wFileData.cFileName;
|
||||
result = PyUnicode_FromWideChar(wRealFileName, wcslen(wRealFileName));
|
||||
FindClose(hFindFile);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
os._getvolumepathname
|
||||
|
|
@ -15961,6 +15992,7 @@ static PyMethodDef posix_methods[] = {
|
|||
OS__GETFULLPATHNAME_METHODDEF
|
||||
OS__GETDISKUSAGE_METHODDEF
|
||||
OS__GETFINALPATHNAME_METHODDEF
|
||||
OS__FINDFIRSTFILE_METHODDEF
|
||||
OS__GETVOLUMEPATHNAME_METHODDEF
|
||||
OS__PATH_SPLITROOT_METHODDEF
|
||||
OS__PATH_NORMPATH_METHODDEF
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue