@@ -4350,42 +4350,34 @@ os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
43504350
43514351
43524352#if defined(MS_WINDOWS ) && !defined(HAVE_OPENDIR )
4353+ static wchar_t *
4354+ join_path_filenameW (const wchar_t * path_wide , const wchar_t * filename ,
4355+ int normalize );
4356+
43534357static PyObject *
43544358_listdir_windows_no_opendir (path_t * path , PyObject * list )
43554359{
43564360 PyObject * v ;
43574361 HANDLE hFindFile = INVALID_HANDLE_VALUE ;
43584362 BOOL result , return_bytes ;
4359- wchar_t namebuf [MAX_PATH + 4 ]; /* Overallocate for "\*.*" */
4360- /* only claim to have space for MAX_PATH */
4361- Py_ssize_t len = Py_ARRAY_LENGTH (namebuf )- 4 ;
43624363 wchar_t * wnamebuf = NULL ;
43634364
43644365 WIN32_FIND_DATAW wFileData ;
43654366 const wchar_t * po_wchars ;
43664367
43674368 if (!path -> wide ) { /* Default arg: "." */
43684369 po_wchars = L"." ;
4369- len = 1 ;
43704370 return_bytes = 0 ;
43714371 } else {
43724372 po_wchars = path -> wide ;
4373- len = wcslen (path -> wide );
43744373 return_bytes = PyBytes_Check (path -> object );
43754374 }
4376- /* The +5 is so we can append "\\*.*\0" */
4377- wnamebuf = PyMem_New (wchar_t , len + 5 );
4378- if (!wnamebuf ) {
4379- PyErr_NoMemory ();
4375+
4376+ wnamebuf = join_path_filenameW (po_wchars , L"*.*" , 1 );
4377+ if (wnamebuf == NULL ) {
43804378 goto exit ;
43814379 }
4382- wcscpy (wnamebuf , po_wchars );
4383- if (len > 0 ) {
4384- wchar_t wch = wnamebuf [len - 1 ];
4385- if (wch != SEP && wch != ALTSEP && wch != L':' )
4386- wnamebuf [len ++ ] = SEP ;
4387- wcscpy (wnamebuf + len , L"*.*" );
4388- }
4380+
43894381 if ((list = PyList_New (0 )) == NULL ) {
43904382 goto exit ;
43914383 }
@@ -15933,13 +15925,19 @@ static PyType_Spec DirEntryType_spec = {
1593315925
1593415926#ifdef MS_WINDOWS
1593515927
15928+ static int
15929+ is_extended_path (const wchar_t * path )
15930+ {
15931+ return wcsncmp (path , L"\\\\?\\" , 4 ) == 0 ;
15932+ }
15933+
1593615934static wchar_t *
15937- join_path_filenameW (const wchar_t * path_wide , const wchar_t * filename )
15935+ join_path_filenameW (const wchar_t * path_wide , const wchar_t * filename ,
15936+ int normalize )
1593815937{
1593915938 Py_ssize_t path_len ;
15940- Py_ssize_t size ;
1594115939 wchar_t * result ;
15942- wchar_t ch ;
15940+ wchar_t * path_allocated = NULL ;
1594315941
1594415942 if (!path_wide ) { /* Default arg: "." */
1594515943 path_wide = L"." ;
@@ -15949,20 +15947,44 @@ join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
1594915947 path_len = wcslen (path_wide );
1595015948 }
1595115949
15952- /* The +1's are for the path separator and the NUL */
15953- size = path_len + 1 + wcslen (filename ) + 1 ;
15950+ if (path_len == 0 ) {
15951+ result = PyMem_New (wchar_t , 1 );
15952+ if (result == NULL ) {
15953+ PyErr_NoMemory ();
15954+ return NULL ;
15955+ }
15956+ result [0 ] = L'\0' ;
15957+ return result ;
15958+ }
15959+
15960+ if (normalize && !is_extended_path (path_wide )) {
15961+ int err = _PyOS_getfullpathname (path_wide , & path_allocated );
15962+ if (err < 0 ) {
15963+ PyErr_SetFromWindowsErr (0 );
15964+ return NULL ;
15965+ }
15966+ if (path_allocated == NULL ) {
15967+ PyErr_NoMemory ();
15968+ return NULL ;
15969+ }
15970+ path_wide = path_allocated ;
15971+ path_len = wcslen (path_wide );
15972+ }
15973+
15974+ size_t size = (size_t )path_len + 1 + wcslen (filename ) + 1 ;
1595415975 result = PyMem_New (wchar_t , size );
15955- if (!result ) {
15976+ if (result == NULL ) {
15977+ PyMem_RawFree (path_allocated );
1595615978 PyErr_NoMemory ();
1595715979 return NULL ;
1595815980 }
1595915981 wcscpy (result , path_wide );
15960- if (path_len > 0 ) {
15961- ch = result [path_len - 1 ];
15962- if (ch != SEP && ch != ALTSEP && ch != L':' )
15963- result [path_len ++ ] = SEP ;
15964- wcscpy (result + path_len , filename );
15982+ wchar_t ch = result [path_len - 1 ];
15983+ if (ch != SEP && ch != ALTSEP && ch != L':' ) {
15984+ result [path_len ++ ] = SEP ;
1596515985 }
15986+ wcscpy (result + path_len , filename );
15987+ PyMem_RawFree (path_allocated );
1596615988 return result ;
1596715989}
1596815990
@@ -15994,7 +16016,7 @@ DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
1599416016 goto error ;
1599516017 }
1599616018
15997- joined_path = join_path_filenameW (path -> wide , dataW -> cFileName );
16019+ joined_path = join_path_filenameW (path -> wide , dataW -> cFileName , 0 );
1599816020 if (!joined_path )
1599916021 goto error ;
1600016022
@@ -16418,7 +16440,7 @@ os_scandir_impl(PyObject *module, path_t *path)
1641816440#ifdef MS_WINDOWS
1641916441 iterator -> first_time = 1 ;
1642016442
16421- path_strW = join_path_filenameW (iterator -> path .wide , L"*.*" );
16443+ path_strW = join_path_filenameW (iterator -> path .wide , L"*.*" , 1 );
1642216444 if (!path_strW )
1642316445 goto error ;
1642416446
0 commit comments