@@ -266,6 +266,41 @@ join(wchar_t *buffer, const wchar_t *stuff)
266
266
}
267
267
}
268
268
269
+ static int _PathCchCanonicalizeEx_Initialized = 0 ;
270
+ typedef HRESULT (__stdcall * PPathCchCanonicalizeEx ) (PWSTR pszPathOut , size_t cchPathOut ,
271
+ PCWSTR pszPathIn , unsigned long dwFlags );
272
+ static PPathCchCanonicalizeEx _PathCchCanonicalizeEx ;
273
+
274
+ static _PyInitError canonicalize (wchar_t * buffer , const wchar_t * path )
275
+ {
276
+ if (buffer == NULL ) {
277
+ return _Py_INIT_NO_MEMORY ();
278
+ }
279
+
280
+ if (_PathCchCanonicalizeEx_Initialized == 0 ) {
281
+ HMODULE pathapi = LoadLibraryW (L"api-ms-win-core-path-l1-1-0.dll" );
282
+ if (pathapi ) {
283
+ _PathCchCanonicalizeEx = (PPathCchCanonicalizeEx )GetProcAddress (pathapi , "PathCchCanonicalizeEx" );
284
+ }
285
+ else {
286
+ _PathCchCanonicalizeEx = NULL ;
287
+ }
288
+ _PathCchCanonicalizeEx_Initialized = 1 ;
289
+ }
290
+
291
+ if (_PathCchCanonicalizeEx ) {
292
+ if (FAILED (_PathCchCanonicalizeEx (buffer , MAXPATHLEN + 1 , path , 0 ))) {
293
+ return _Py_INIT_ERR ("buffer overflow in getpathp.c's canonicalize()" );
294
+ }
295
+ }
296
+ else {
297
+ if (!PathCanonicalizeW (buffer , path )) {
298
+ return _Py_INIT_ERR ("buffer overflow in getpathp.c's canonicalize()" );
299
+ }
300
+ }
301
+ return _Py_INIT_OK ();
302
+ }
303
+
269
304
270
305
/* gotlandmark only called by search_for_prefix, which ensures
271
306
'prefix' is null terminated in bounds. join() ensures
@@ -504,63 +539,16 @@ get_program_full_path(const _PyCoreConfig *core_config,
504
539
wchar_t program_full_path [MAXPATHLEN + 1 ];
505
540
memset (program_full_path , 0 , sizeof (program_full_path ));
506
541
507
- if (GetModuleFileNameW (NULL , program_full_path , MAXPATHLEN )) {
508
- goto done ;
509
- }
510
-
511
- /* If there is no slash in the argv0 path, then we have to
512
- * assume python is on the user's $PATH, since there's no
513
- * other way to find a directory to start the search from. If
514
- * $PATH isn't exported, you lose.
515
- */
516
- #ifdef ALTSEP
517
- if (wcschr (core_config -> program_name , SEP ) ||
518
- wcschr (core_config -> program_name , ALTSEP ))
519
- #else
520
- if (wcschr (core_config -> program_name , SEP ))
521
- #endif
522
- {
523
- wcsncpy (program_full_path , core_config -> program_name , MAXPATHLEN );
542
+ if (!GetModuleFileNameW (NULL , program_full_path , MAXPATHLEN )) {
543
+ /* GetModuleFileName should never fail when passed NULL */
544
+ return _Py_INIT_ERR ("Cannot determine program path" );
524
545
}
525
- else if (calculate -> path_env ) {
526
- const wchar_t * path = calculate -> path_env ;
527
- while (1 ) {
528
- const wchar_t * delim = wcschr (path , DELIM );
529
-
530
- if (delim ) {
531
- size_t len = delim - path ;
532
- /* ensure we can't overwrite buffer */
533
- len = min (MAXPATHLEN ,len );
534
- wcsncpy (program_full_path , path , len );
535
- program_full_path [len ] = '\0' ;
536
- }
537
- else {
538
- wcsncpy (program_full_path , path , MAXPATHLEN );
539
- }
540
-
541
- /* join() is safe for MAXPATHLEN+1 size buffer */
542
- join (program_full_path , core_config -> program_name );
543
- if (exists (program_full_path )) {
544
- break ;
545
- }
546
546
547
- if (!delim ) {
548
- program_full_path [0 ] = '\0' ;
549
- break ;
550
- }
551
- path = delim + 1 ;
552
- }
553
- }
554
- else {
555
- program_full_path [0 ] = '\0' ;
556
- }
547
+ config -> program_full_path = PyMem_RawMalloc (
548
+ sizeof (wchar_t ) * (MAXPATHLEN + 1 ));
557
549
558
- done :
559
- config -> program_full_path = _PyMem_RawWcsdup (program_full_path );
560
- if (config -> program_full_path == NULL ) {
561
- return _Py_INIT_NO_MEMORY ();
562
- }
563
- return _Py_INIT_OK ();
550
+ return canonicalize (config -> program_full_path ,
551
+ program_full_path );
564
552
}
565
553
566
554
0 commit comments