mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
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:
parent
b8ddf7e794
commit
d4e64cd4b0
8 changed files with 114 additions and 42 deletions
|
@ -59,7 +59,7 @@ getpath_abspath(PyObject *Py_UNUSED(self), PyObject *args)
|
|||
{
|
||||
PyObject *r = NULL;
|
||||
PyObject *pathobj;
|
||||
const wchar_t *path;
|
||||
wchar_t *path;
|
||||
if (!PyArg_ParseTuple(args, "U", &pathobj)) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -67,8 +67,8 @@ getpath_abspath(PyObject *Py_UNUSED(self), PyObject *args)
|
|||
path = PyUnicode_AsWideCharString(pathobj, &len);
|
||||
if (path) {
|
||||
wchar_t *abs;
|
||||
if (_Py_abspath(path, &abs) == 0 && abs) {
|
||||
r = PyUnicode_FromWideChar(_Py_normpath(abs, -1), -1);
|
||||
if (_Py_abspath((const wchar_t *)_Py_normpath(path, -1), &abs) == 0 && abs) {
|
||||
r = PyUnicode_FromWideChar(abs, -1);
|
||||
PyMem_RawFree((void *)abs);
|
||||
} else {
|
||||
PyErr_SetString(PyExc_OSError, "failed to make path absolute");
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue