mirror of https://github.com/python/cpython
Dynamically allocate path name buffer for Unicode
path name in listdir. Fixes #1431582. Stop overallocating MAX_PATH characters for ANSI path names. Stop assigning to errno.
This commit is contained in:
parent
b06d28c160
commit
682b1bb95f
|
@ -72,6 +72,9 @@ Core and builtins
|
||||||
Extension Modules
|
Extension Modules
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- On Win32, os.listdir now supports arbitrarily-long Unicode path names
|
||||||
|
(up to the system limit of 32K characters).
|
||||||
|
|
||||||
- Use Win32 API to implement os.{access,chdir,chmod,mkdir,remove,rename,rmdir,utime}.
|
- Use Win32 API to implement os.{access,chdir,chmod,mkdir,remove,rename,rmdir,utime}.
|
||||||
As a result, these functions now raise WindowsError instead of OSError.
|
As a result, these functions now raise WindowsError instead of OSError.
|
||||||
|
|
||||||
|
|
|
@ -1782,37 +1782,46 @@ posix_listdir(PyObject *self, PyObject *args)
|
||||||
HANDLE hFindFile;
|
HANDLE hFindFile;
|
||||||
BOOL result;
|
BOOL result;
|
||||||
WIN32_FIND_DATA FileData;
|
WIN32_FIND_DATA FileData;
|
||||||
/* MAX_PATH characters could mean a bigger encoded string */
|
char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
|
||||||
char namebuf[MAX_PATH*2+5];
|
|
||||||
char *bufptr = namebuf;
|
char *bufptr = namebuf;
|
||||||
Py_ssize_t len = sizeof(namebuf)/sizeof(namebuf[0]);
|
Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
|
||||||
|
|
||||||
#ifdef Py_WIN_WIDE_FILENAMES
|
#ifdef Py_WIN_WIDE_FILENAMES
|
||||||
/* If on wide-character-capable OS see if argument
|
/* If on wide-character-capable OS see if argument
|
||||||
is Unicode and if so use wide API. */
|
is Unicode and if so use wide API. */
|
||||||
if (unicode_file_names()) {
|
if (unicode_file_names()) {
|
||||||
PyUnicodeObject *po;
|
PyObject *po;
|
||||||
if (PyArg_ParseTuple(args, "U:listdir", &po)) {
|
if (PyArg_ParseTuple(args, "U:listdir", &po)) {
|
||||||
WIN32_FIND_DATAW wFileData;
|
WIN32_FIND_DATAW wFileData;
|
||||||
Py_UNICODE wnamebuf[MAX_PATH*2+5];
|
Py_UNICODE *wnamebuf;
|
||||||
Py_UNICODE wch;
|
Py_UNICODE wch;
|
||||||
wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
|
/* Overallocate for \\*.*\0 */
|
||||||
wnamebuf[MAX_PATH] = L'\0';
|
len = PyUnicode_GET_SIZE(po);
|
||||||
len = wcslen(wnamebuf);
|
wnamebuf = malloc((len + 5) * sizeof(wchar_t));
|
||||||
wch = (len > 0) ? wnamebuf[len-1] : L'\0';
|
if (!wnamebuf) {
|
||||||
if (wch != L'/' && wch != L'\\' && wch != L':')
|
PyErr_NoMemory();
|
||||||
wnamebuf[len++] = L'/';
|
|
||||||
wcscpy(wnamebuf + len, L"*.*");
|
|
||||||
if ((d = PyList_New(0)) == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
|
||||||
|
wch = len > 0 ? wnamebuf[len-1] : '\0';
|
||||||
|
if (wch != L'/' && wch != L'\\' && wch != L':')
|
||||||
|
wnamebuf[len++] = L'\\';
|
||||||
|
wcscpy(wnamebuf + len, L"*.*");
|
||||||
|
if ((d = PyList_New(0)) == NULL) {
|
||||||
|
free(wnamebuf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
hFindFile = FindFirstFileW(wnamebuf, &wFileData);
|
hFindFile = FindFirstFileW(wnamebuf, &wFileData);
|
||||||
if (hFindFile == INVALID_HANDLE_VALUE) {
|
if (hFindFile == INVALID_HANDLE_VALUE) {
|
||||||
errno = GetLastError();
|
int error = GetLastError();
|
||||||
if (errno == ERROR_FILE_NOT_FOUND) {
|
if (error == ERROR_FILE_NOT_FOUND) {
|
||||||
|
free(wnamebuf);
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
Py_DECREF(d);
|
Py_DECREF(d);
|
||||||
return win32_error_unicode("FindFirstFileW", wnamebuf);
|
win32_error_unicode("FindFirstFileW", wnamebuf);
|
||||||
|
free(wnamebuf);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
/* Skip over . and .. */
|
/* Skip over . and .. */
|
||||||
|
@ -1839,7 +1848,9 @@ posix_listdir(PyObject *self, PyObject *args)
|
||||||
|
|
||||||
if (FindClose(hFindFile) == FALSE) {
|
if (FindClose(hFindFile) == FALSE) {
|
||||||
Py_DECREF(d);
|
Py_DECREF(d);
|
||||||
return win32_error_unicode("FindClose", wnamebuf);
|
win32_error_unicode("FindClose", wnamebuf);
|
||||||
|
free(wnamebuf);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
@ -1864,8 +1875,8 @@ posix_listdir(PyObject *self, PyObject *args)
|
||||||
|
|
||||||
hFindFile = FindFirstFile(namebuf, &FileData);
|
hFindFile = FindFirstFile(namebuf, &FileData);
|
||||||
if (hFindFile == INVALID_HANDLE_VALUE) {
|
if (hFindFile == INVALID_HANDLE_VALUE) {
|
||||||
errno = GetLastError();
|
int error = GetLastError();
|
||||||
if (errno == ERROR_FILE_NOT_FOUND)
|
if (error == ERROR_FILE_NOT_FOUND)
|
||||||
return d;
|
return d;
|
||||||
Py_DECREF(d);
|
Py_DECREF(d);
|
||||||
return win32_error("FindFirstFile", namebuf);
|
return win32_error("FindFirstFile", namebuf);
|
||||||
|
|
Loading…
Reference in New Issue