Skip to content

Commit ebac19d

Browse files
authored
bpo-32030: Don't call _PyPathConfig_Fini() in Py_FinalizeEx() (python#4667)
Changes: * _PyPathConfig_Fini() cannot be called in Py_FinalizeEx(). Py_Initialize() and Py_Finalize() can be called multiple times, but it must not "forget" parameters set by Py_SetProgramName(), Py_SetPath() or Py_SetPythonHome(), whereas _PyPathConfig_Fini() clear all these parameters. * config_get_program_name() and calculate_program_full_path() now also decode paths using Py_DecodeLocale() to use the surrogateescape error handler, rather than decoding using mbstowcs() which is strict. * Change _Py_CheckPython3() prototype: () => (void) * Truncate a few lines which were too long
1 parent 9ac3d88 commit ebac19d

File tree

5 files changed

+38
-25
lines changed

5 files changed

+38
-25
lines changed

Include/pylifecycle.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ PyAPI_FUNC(void) _PyPathConfig_Fini(void);
109109
#endif
110110
PyAPI_FUNC(void) Py_SetPath(const wchar_t *);
111111
#ifdef MS_WINDOWS
112-
int _Py_CheckPython3();
112+
int _Py_CheckPython3(void);
113113
#endif
114114

115115
/* In their own files */

Modules/getpath.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -625,11 +625,13 @@ calculate_program_full_path(const _PyMainInterpreterConfig *main_config,
625625
else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) &&
626626
execpath[0] == SEP)
627627
{
628-
size_t r = mbstowcs(program_full_path, execpath, MAXPATHLEN+1);
629-
if (r == (size_t)-1 || r > MAXPATHLEN) {
630-
/* Could not convert execpath, or it's too long. */
631-
program_full_path[0] = '\0';
628+
size_t len;
629+
wchar_t *path = Py_DecodeLocale(execpath, &len);
630+
if (path == NULL) {
631+
return DECODE_LOCALE_ERR("executable path", len);
632632
}
633+
wcsncpy(program_full_path, path, MAXPATHLEN);
634+
PyMem_RawFree(path);
633635
}
634636
#endif /* __APPLE__ */
635637
else if (calculate->path_env) {

Modules/main.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -888,15 +888,12 @@ config_get_program_name(_PyMainInterpreterConfig *config)
888888
See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
889889
script. */
890890
if ((p = Py_GETENV("PYTHONEXECUTABLE")) && *p != '\0') {
891-
wchar_t* buffer;
892-
size_t len = strlen(p) + 1;
893-
894-
buffer = PyMem_RawMalloc(len * sizeof(wchar_t));
895-
if (buffer == NULL) {
896-
return _Py_INIT_NO_MEMORY();
891+
size_t len;
892+
wchar_t* program_name = Py_DecodeLocale(p, &len);
893+
if (program_name == NULL) {
894+
return SET_DECODE_ERROR("PYTHONEXECUTABLE environment "
895+
"variable", len);
897896
}
898-
899-
mbstowcs(buffer, p, len);
900897
pymain->config.program_name = buffer;
901898
}
902899
#ifdef WITH_NEXT_FRAMEWORK
@@ -907,11 +904,12 @@ config_get_program_name(_PyMainInterpreterConfig *config)
907904
* the argv0 of the stub executable
908905
*/
909906
size_t len;
910-
wchar_t* wbuf = Py_DecodeLocale(pyvenv_launcher, &len);
911-
if (wbuf == NULL) {
912-
return SET_DECODE_ERROR("__PYVENV_LAUNCHER__", len);
907+
wchar_t* program_name = Py_DecodeLocale(pyvenv_launcher, &len);
908+
if (program_name == NULL) {
909+
return SET_DECODE_ERROR("__PYVENV_LAUNCHER__ environment "
910+
"variable", len);
913911
}
914-
pymain->config.program_name = wbuf;
912+
pymain->config.program_name = program_name;
915913
}
916914
}
917915
#endif /* WITH_NEXT_FRAMEWORK */
@@ -1666,6 +1664,14 @@ pymain_impl(_PyMain *pymain)
16661664
other special meaning */
16671665
pymain->status = 120;
16681666
}
1667+
1668+
/* _PyPathConfig_Fini() cannot be called in Py_FinalizeEx().
1669+
Py_Initialize() and Py_Finalize() can be called multiple times, but it
1670+
must not "forget" parameters set by Py_SetProgramName(), Py_SetPath() or
1671+
Py_SetPythonHome(), whereas _PyPathConfig_Fini() clear all these
1672+
parameters. */
1673+
_PyPathConfig_Fini();
1674+
16691675
return 0;
16701676
}
16711677

PC/getpathp.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -721,12 +721,16 @@ static int
721721
get_pth_filename(wchar_t *spbuffer, _PyPathConfig *config)
722722
{
723723
if (config->dll_path[0]) {
724-
if (!change_ext(spbuffer, config->dll_path, L"._pth") && exists(spbuffer)) {
724+
if (!change_ext(spbuffer, config->dll_path, L"._pth") &&
725+
exists(spbuffer))
726+
{
725727
return 1;
726728
}
727729
}
728730
if (config->program_full_path[0]) {
729-
if (!change_ext(spbuffer, config->program_full_path, L"._pth") && exists(spbuffer)) {
731+
if (!change_ext(spbuffer, config->program_full_path, L"._pth") &&
732+
exists(spbuffer))
733+
{
730734
return 1;
731735
}
732736
}
@@ -823,8 +827,10 @@ calculate_module_search_path(const _PyMainInterpreterConfig *main_config,
823827
#endif
824828
/* We only use the default relative PYTHONPATH if we haven't
825829
anything better to use! */
826-
int skipdefault = (main_config->module_search_path_env!=NULL || calculate->home!=NULL || \
827-
calculate->machine_path!=NULL || calculate->user_path!=NULL);
830+
int skipdefault = (main_config->module_search_path_env != NULL ||
831+
calculate->home != NULL ||
832+
calculate->machine_path != NULL ||
833+
calculate->user_path != NULL);
828834

829835
/* We need to construct a path from the following parts.
830836
(1) the PYTHONPATH environment variable, if set;
@@ -882,7 +888,8 @@ calculate_module_search_path(const _PyMainInterpreterConfig *main_config,
882888
start_buf = buf;
883889

884890
if (main_config->module_search_path_env) {
885-
if (wcscpy_s(buf, bufsz - (buf - start_buf), main_config->module_search_path_env)) {
891+
if (wcscpy_s(buf, bufsz - (buf - start_buf),
892+
main_config->module_search_path_env)) {
886893
return INIT_ERR_BUFFER_OVERFLOW();
887894
}
888895
buf = wcschr(buf, L'\0');
@@ -1214,7 +1221,7 @@ Py_GetProgramFullPath(void)
12141221
static int python3_checked = 0;
12151222
static HANDLE hPython3;
12161223
int
1217-
_Py_CheckPython3()
1224+
_Py_CheckPython3(void)
12181225
{
12191226
wchar_t py3path[MAXPATHLEN+1];
12201227
wchar_t *s;

Python/pylifecycle.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,8 +1273,6 @@ Py_FinalizeEx(void)
12731273

12741274
call_ll_exitfuncs();
12751275

1276-
_PyPathConfig_Fini();
1277-
12781276
_PyRuntime_Finalize();
12791277
return status;
12801278
}

0 commit comments

Comments
 (0)