Skip to content

Commit ae4836d

Browse files
author
Victor Stinner
committed
Issue #6011: decode PREFIX, EXEC_PREFIX and PYTHONPATH variables using
_Py_char2wchar(), instead of L"" VAR hack, to escape undecodable bytes using the surrogateescape error handler.
1 parent d5af0a5 commit ae4836d

1 file changed

Lines changed: 30 additions & 17 deletions

File tree

Modules/getpath.c

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ absolutize(wchar_t *path)
263263
bytes long.
264264
*/
265265
static int
266-
search_for_prefix(wchar_t *argv0_path, wchar_t *home)
266+
search_for_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_prefix)
267267
{
268268
size_t n;
269269
wchar_t *vpath;
@@ -310,7 +310,7 @@ search_for_prefix(wchar_t *argv0_path, wchar_t *home)
310310
} while (prefix[0]);
311311

312312
/* Look at configure's PREFIX */
313-
wcsncpy(prefix, L"" PREFIX, MAXPATHLEN);
313+
wcsncpy(prefix, _prefix, MAXPATHLEN);
314314
joinpath(prefix, lib_python);
315315
joinpath(prefix, LANDMARK);
316316
if (ismodule(prefix))
@@ -325,7 +325,7 @@ search_for_prefix(wchar_t *argv0_path, wchar_t *home)
325325
MAXPATHLEN bytes long.
326326
*/
327327
static int
328-
search_for_exec_prefix(wchar_t *argv0_path, wchar_t *home)
328+
search_for_exec_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_exec_prefix)
329329
{
330330
size_t n;
331331

@@ -387,7 +387,7 @@ search_for_exec_prefix(wchar_t *argv0_path, wchar_t *home)
387387
} while (exec_prefix[0]);
388388

389389
/* Look at configure's EXEC_PREFIX */
390-
wcsncpy(exec_prefix, L"" EXEC_PREFIX, MAXPATHLEN);
390+
wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN);
391391
joinpath(exec_prefix, lib_python);
392392
joinpath(exec_prefix, L"lib-dynload");
393393
if (isdir(exec_prefix))
@@ -397,15 +397,13 @@ search_for_exec_prefix(wchar_t *argv0_path, wchar_t *home)
397397
return 0;
398398
}
399399

400-
401400
static void
402401
calculate_path(void)
403402
{
404403
extern wchar_t *Py_GetProgramName(void);
405404

406405
static wchar_t delimiter[2] = {DELIM, '\0'};
407406
static wchar_t separator[2] = {SEP, '\0'};
408-
wchar_t *pythonpath = L"" PYTHONPATH;
409407
char *_rtpypath = Py_GETENV("PYTHONPATH"); /* XXX use wide version on Windows */
410408
wchar_t rtpypath[MAXPATHLEN+1];
411409
wchar_t *home = Py_GetPythonHome();
@@ -419,7 +417,7 @@ calculate_path(void)
419417
wchar_t *buf;
420418
size_t bufsz;
421419
size_t prefixsz;
422-
wchar_t *defpath = pythonpath;
420+
wchar_t *defpath;
423421
#ifdef WITH_NEXT_FRAMEWORK
424422
NSModule pythonModule;
425423
#endif
@@ -429,8 +427,19 @@ calculate_path(void)
429427
#else
430428
unsigned long nsexeclength = MAXPATHLEN;
431429
#endif
432-
char execpath[MAXPATHLEN+1];
430+
char execpath[MAXPATHLEN+1];
433431
#endif
432+
wchar_t *_pythonpath, *_prefix, *_exec_prefix;
433+
434+
_pythonpath = _Py_char2wchar(PYTHONPATH, NULL);
435+
_prefix = _Py_char2wchar(PREFIX, NULL);
436+
_exec_prefix = _Py_char2wchar(EXEC_PREFIX, NULL);
437+
438+
if (!_pythonpath || !_prefix || !_exec_prefix) {
439+
Py_FatalError(
440+
"Unable to decode path variables in getpath.c: "
441+
"memory error");
442+
}
434443

435444
if (_path) {
436445
path_buffer = _Py_char2wchar(_path, NULL);
@@ -555,11 +564,11 @@ calculate_path(void)
555564
MAXPATHLEN bytes long.
556565
*/
557566

558-
if (!(pfound = search_for_prefix(argv0_path, home))) {
567+
if (!(pfound = search_for_prefix(argv0_path, home, _prefix))) {
559568
if (!Py_FrozenFlag)
560569
fprintf(stderr,
561570
"Could not find platform independent libraries <prefix>\n");
562-
wcsncpy(prefix, L"" PREFIX, MAXPATHLEN);
571+
wcsncpy(prefix, _prefix, MAXPATHLEN);
563572
joinpath(prefix, lib_python);
564573
}
565574
else
@@ -572,17 +581,17 @@ calculate_path(void)
572581
reduce(zip_path);
573582
}
574583
else
575-
wcsncpy(zip_path, L"" PREFIX, MAXPATHLEN);
584+
wcsncpy(zip_path, _prefix, MAXPATHLEN);
576585
joinpath(zip_path, L"lib/python00.zip");
577586
bufsz = wcslen(zip_path); /* Replace "00" with version */
578587
zip_path[bufsz - 6] = VERSION[0];
579588
zip_path[bufsz - 5] = VERSION[2];
580589

581-
if (!(efound = search_for_exec_prefix(argv0_path, home))) {
590+
if (!(efound = search_for_exec_prefix(argv0_path, home, _exec_prefix))) {
582591
if (!Py_FrozenFlag)
583592
fprintf(stderr,
584593
"Could not find platform dependent libraries <exec_prefix>\n");
585-
wcsncpy(exec_prefix, L"" EXEC_PREFIX, MAXPATHLEN);
594+
wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN);
586595
joinpath(exec_prefix, L"lib/lib-dynload");
587596
}
588597
/* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */
@@ -604,8 +613,8 @@ calculate_path(void)
604613
bufsz += wcslen(rtpypath) + 1;
605614
}
606615

616+
defpath = _pythonpath;
607617
prefixsz = wcslen(prefix) + 1;
608-
609618
while (1) {
610619
wchar_t *delim = wcschr(defpath, DELIM);
611620

@@ -650,7 +659,7 @@ calculate_path(void)
650659
/* Next goes merge of compile-time $PYTHONPATH with
651660
* dynamically located prefix.
652661
*/
653-
defpath = pythonpath;
662+
defpath = _pythonpath;
654663
while (1) {
655664
wchar_t *delim = wcschr(defpath, DELIM);
656665

@@ -694,7 +703,7 @@ calculate_path(void)
694703
wcscpy(prefix, separator);
695704
}
696705
else
697-
wcsncpy(prefix, L"" PREFIX, MAXPATHLEN);
706+
wcsncpy(prefix, _prefix, MAXPATHLEN);
698707

699708
if (efound > 0) {
700709
reduce(exec_prefix);
@@ -704,7 +713,11 @@ calculate_path(void)
704713
wcscpy(exec_prefix, separator);
705714
}
706715
else
707-
wcsncpy(exec_prefix, L"" EXEC_PREFIX, MAXPATHLEN);
716+
wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN);
717+
718+
PyMem_Free(_pythonpath);
719+
PyMem_Free(_prefix);
720+
PyMem_Free(_exec_prefix);
708721
}
709722

710723

0 commit comments

Comments
 (0)