bpo-46362: Ensure ntpath.abspath() uses the Windows API correctly (GH-30571)

This makes ntpath.abspath()/getpath_abspath() follow normpath(), since some WinAPIs such as PathCchSkipRoot() require backslashed paths.
This commit is contained in:
neonene 2022-01-14 08:35:42 +09:00 committed by GitHub
parent b8ddf7e794
commit d4e64cd4b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 114 additions and 42 deletions

View file

@ -4240,6 +4240,48 @@ os_listdir_impl(PyObject *module, path_t *path)
}
#ifdef MS_WINDOWS
int
_PyOS_getfullpathname(const wchar_t *path, wchar_t **abspath_p)
{
wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
DWORD result;
result = GetFullPathNameW(path,
Py_ARRAY_LENGTH(woutbuf), woutbuf,
NULL);
if (!result) {
return -1;
}
if (result >= Py_ARRAY_LENGTH(woutbuf)) {
if ((size_t)result <= (size_t)PY_SSIZE_T_MAX / sizeof(wchar_t)) {
woutbufp = PyMem_RawMalloc((size_t)result * sizeof(wchar_t));
}
else {
woutbufp = NULL;
}
if (!woutbufp) {
*abspath_p = NULL;
return 0;
}
result = GetFullPathNameW(path, result, woutbufp, NULL);
if (!result) {
PyMem_RawFree(woutbufp);
return -1;
}
}
if (woutbufp != woutbuf) {
*abspath_p = woutbufp;
return 0;
}
*abspath_p = _PyMem_RawWcsdup(woutbufp);
return 0;
}
/* A helper function for abspath on win32 */
/*[clinic input]
os._getfullpathname
@ -4255,8 +4297,7 @@ os__getfullpathname_impl(PyObject *module, path_t *path)
{
wchar_t *abspath;
/* _Py_abspath() is implemented with GetFullPathNameW() on Windows */
if (_Py_abspath(path->wide, &abspath) < 0) {
if (_PyOS_getfullpathname(path->wide, &abspath) < 0) {
return win32_error_object("GetFullPathNameW", path->object);
}
if (abspath == NULL) {