@@ -4905,42 +4905,34 @@ os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
49054905
49064906
49074907#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
4908+ static wchar_t *
4909+ join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename,
4910+ int normalize);
4911+
49084912static PyObject *
49094913_listdir_windows_no_opendir(path_t *path, PyObject *list)
49104914{
49114915 PyObject *v;
49124916 HANDLE hFindFile = INVALID_HANDLE_VALUE;
49134917 BOOL result, return_bytes;
4914- wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
4915- /* only claim to have space for MAX_PATH */
4916- Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
49174918 wchar_t *wnamebuf = NULL;
49184919
49194920 WIN32_FIND_DATAW wFileData;
49204921 const wchar_t *po_wchars;
49214922
49224923 if (!path->wide) { /* Default arg: "." */
49234924 po_wchars = L".";
4924- len = 1;
49254925 return_bytes = 0;
49264926 } else {
49274927 po_wchars = path->wide;
4928- len = wcslen(path->wide);
49294928 return_bytes = PyBytes_Check(path->object);
49304929 }
4931- /* The +5 is so we can append "\\*.*\0" */
4932- wnamebuf = PyMem_New(wchar_t, len + 5);
4933- if (!wnamebuf) {
4934- PyErr_NoMemory();
4930+
4931+ wnamebuf = join_path_filenameW(po_wchars, L"*.*", 1);
4932+ if (wnamebuf == NULL) {
49354933 goto exit;
49364934 }
4937- wcscpy(wnamebuf, po_wchars);
4938- if (len > 0) {
4939- wchar_t wch = wnamebuf[len-1];
4940- if (wch != SEP && wch != ALTSEP && wch != L':')
4941- wnamebuf[len++] = SEP;
4942- wcscpy(wnamebuf + len, L"*.*");
4943- }
4935+
49444936 if ((list = PyList_New(0)) == NULL) {
49454937 goto exit;
49464938 }
@@ -16608,13 +16600,19 @@ static PyType_Spec DirEntryType_spec = {
1660816600
1660916601#ifdef MS_WINDOWS
1661016602
16603+ static int
16604+ is_extended_path(const wchar_t *path)
16605+ {
16606+ return wcsncmp(path, L"\\\\?\\", 4) == 0;
16607+ }
16608+
1661116609static wchar_t *
16612- join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
16610+ join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename,
16611+ int normalize)
1661316612{
1661416613 Py_ssize_t path_len;
16615- Py_ssize_t size;
1661616614 wchar_t *result;
16617- wchar_t ch ;
16615+ wchar_t *path_allocated = NULL ;
1661816616
1661916617 if (!path_wide) { /* Default arg: "." */
1662016618 path_wide = L".";
@@ -16624,20 +16622,44 @@ join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
1662416622 path_len = wcslen(path_wide);
1662516623 }
1662616624
16627- /* The +1's are for the path separator and the NUL */
16628- size = path_len + 1 + wcslen(filename) + 1;
16625+ if (path_len == 0) {
16626+ result = PyMem_New(wchar_t, 1);
16627+ if (result == NULL) {
16628+ PyErr_NoMemory();
16629+ return NULL;
16630+ }
16631+ result[0] = L'\0';
16632+ return result;
16633+ }
16634+
16635+ if (normalize && !is_extended_path(path_wide)) {
16636+ int err = _PyOS_getfullpathname(path_wide, &path_allocated);
16637+ if (err < 0) {
16638+ PyErr_SetFromWindowsErr(0);
16639+ return NULL;
16640+ }
16641+ if (path_allocated == NULL) {
16642+ PyErr_NoMemory();
16643+ return NULL;
16644+ }
16645+ path_wide = path_allocated;
16646+ path_len = wcslen(path_wide);
16647+ }
16648+
16649+ size_t size = (size_t)path_len + 1 + wcslen(filename) + 1;
1662916650 result = PyMem_New(wchar_t, size);
16630- if (!result) {
16651+ if (result == NULL) {
16652+ PyMem_RawFree(path_allocated);
1663116653 PyErr_NoMemory();
1663216654 return NULL;
1663316655 }
1663416656 wcscpy(result, path_wide);
16635- if (path_len > 0) {
16636- ch = result[path_len - 1];
16637- if (ch != SEP && ch != ALTSEP && ch != L':')
16638- result[path_len++] = SEP;
16639- wcscpy(result + path_len, filename);
16657+ wchar_t ch = result[path_len - 1];
16658+ if (ch != SEP && ch != ALTSEP && ch != L':') {
16659+ result[path_len++] = SEP;
1664016660 }
16661+ wcscpy(result + path_len, filename);
16662+ PyMem_RawFree(path_allocated);
1664116663 return result;
1664216664}
1664316665
@@ -16669,7 +16691,7 @@ DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
1666916691 goto error;
1667016692 }
1667116693
16672- joined_path = join_path_filenameW(path->wide, dataW->cFileName);
16694+ joined_path = join_path_filenameW(path->wide, dataW->cFileName, 0 );
1667316695 if (!joined_path)
1667416696 goto error;
1667516697
@@ -17105,7 +17127,7 @@ os_scandir_impl(PyObject *module, path_t *path)
1710517127#ifdef MS_WINDOWS
1710617128 iterator->first_time = 1;
1710717129
17108- path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
17130+ path_strW = join_path_filenameW(iterator->path.wide, L"*.*", 1 );
1710917131 if (!path_strW)
1711017132 goto error;
1711117133
0 commit comments