Commit ebac19da authored by Victor Stinner's avatar Victor Stinner Committed by GitHub

bpo-32030: Don't call _PyPathConfig_Fini() in Py_FinalizeEx() (#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
parent 9ac3d888
...@@ -109,7 +109,7 @@ PyAPI_FUNC(void) _PyPathConfig_Fini(void); ...@@ -109,7 +109,7 @@ PyAPI_FUNC(void) _PyPathConfig_Fini(void);
#endif #endif
PyAPI_FUNC(void) Py_SetPath(const wchar_t *); PyAPI_FUNC(void) Py_SetPath(const wchar_t *);
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
int _Py_CheckPython3(); int _Py_CheckPython3(void);
#endif #endif
/* In their own files */ /* In their own files */
......
...@@ -625,11 +625,13 @@ calculate_program_full_path(const _PyMainInterpreterConfig *main_config, ...@@ -625,11 +625,13 @@ calculate_program_full_path(const _PyMainInterpreterConfig *main_config,
else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) && else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) &&
execpath[0] == SEP) execpath[0] == SEP)
{ {
size_t r = mbstowcs(program_full_path, execpath, MAXPATHLEN+1); size_t len;
if (r == (size_t)-1 || r > MAXPATHLEN) { wchar_t *path = Py_DecodeLocale(execpath, &len);
/* Could not convert execpath, or it's too long. */ if (path == NULL) {
program_full_path[0] = '\0'; return DECODE_LOCALE_ERR("executable path", len);
} }
wcsncpy(program_full_path, path, MAXPATHLEN);
PyMem_RawFree(path);
} }
#endif /* __APPLE__ */ #endif /* __APPLE__ */
else if (calculate->path_env) { else if (calculate->path_env) {
......
...@@ -888,15 +888,12 @@ config_get_program_name(_PyMainInterpreterConfig *config) ...@@ -888,15 +888,12 @@ config_get_program_name(_PyMainInterpreterConfig *config)
See Lib/plat-mac/bundlebuiler.py for details about the bootstrap See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
script. */ script. */
if ((p = Py_GETENV("PYTHONEXECUTABLE")) && *p != '\0') { if ((p = Py_GETENV("PYTHONEXECUTABLE")) && *p != '\0') {
wchar_t* buffer; size_t len;
size_t len = strlen(p) + 1; wchar_t* program_name = Py_DecodeLocale(p, &len);
if (program_name == NULL) {
buffer = PyMem_RawMalloc(len * sizeof(wchar_t)); return SET_DECODE_ERROR("PYTHONEXECUTABLE environment "
if (buffer == NULL) { "variable", len);
return _Py_INIT_NO_MEMORY();
} }
mbstowcs(buffer, p, len);
pymain->config.program_name = buffer; pymain->config.program_name = buffer;
} }
#ifdef WITH_NEXT_FRAMEWORK #ifdef WITH_NEXT_FRAMEWORK
...@@ -907,11 +904,12 @@ config_get_program_name(_PyMainInterpreterConfig *config) ...@@ -907,11 +904,12 @@ config_get_program_name(_PyMainInterpreterConfig *config)
* the argv0 of the stub executable * the argv0 of the stub executable
*/ */
size_t len; size_t len;
wchar_t* wbuf = Py_DecodeLocale(pyvenv_launcher, &len); wchar_t* program_name = Py_DecodeLocale(pyvenv_launcher, &len);
if (wbuf == NULL) { if (program_name == NULL) {
return SET_DECODE_ERROR("__PYVENV_LAUNCHER__", len); return SET_DECODE_ERROR("__PYVENV_LAUNCHER__ environment "
"variable", len);
} }
pymain->config.program_name = wbuf; pymain->config.program_name = program_name;
} }
} }
#endif /* WITH_NEXT_FRAMEWORK */ #endif /* WITH_NEXT_FRAMEWORK */
...@@ -1666,6 +1664,14 @@ pymain_impl(_PyMain *pymain) ...@@ -1666,6 +1664,14 @@ pymain_impl(_PyMain *pymain)
other special meaning */ other special meaning */
pymain->status = 120; pymain->status = 120;
} }
/* _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. */
_PyPathConfig_Fini();
return 0; return 0;
} }
......
...@@ -721,12 +721,16 @@ static int ...@@ -721,12 +721,16 @@ static int
get_pth_filename(wchar_t *spbuffer, _PyPathConfig *config) get_pth_filename(wchar_t *spbuffer, _PyPathConfig *config)
{ {
if (config->dll_path[0]) { if (config->dll_path[0]) {
if (!change_ext(spbuffer, config->dll_path, L"._pth") && exists(spbuffer)) { if (!change_ext(spbuffer, config->dll_path, L"._pth") &&
exists(spbuffer))
{
return 1; return 1;
} }
} }
if (config->program_full_path[0]) { if (config->program_full_path[0]) {
if (!change_ext(spbuffer, config->program_full_path, L"._pth") && exists(spbuffer)) { if (!change_ext(spbuffer, config->program_full_path, L"._pth") &&
exists(spbuffer))
{
return 1; return 1;
} }
} }
...@@ -823,8 +827,10 @@ calculate_module_search_path(const _PyMainInterpreterConfig *main_config, ...@@ -823,8 +827,10 @@ calculate_module_search_path(const _PyMainInterpreterConfig *main_config,
#endif #endif
/* We only use the default relative PYTHONPATH if we haven't /* We only use the default relative PYTHONPATH if we haven't
anything better to use! */ anything better to use! */
int skipdefault = (main_config->module_search_path_env!=NULL || calculate->home!=NULL || \ int skipdefault = (main_config->module_search_path_env != NULL ||
calculate->machine_path!=NULL || calculate->user_path!=NULL); calculate->home != NULL ||
calculate->machine_path != NULL ||
calculate->user_path != NULL);
/* We need to construct a path from the following parts. /* We need to construct a path from the following parts.
(1) the PYTHONPATH environment variable, if set; (1) the PYTHONPATH environment variable, if set;
...@@ -882,7 +888,8 @@ calculate_module_search_path(const _PyMainInterpreterConfig *main_config, ...@@ -882,7 +888,8 @@ calculate_module_search_path(const _PyMainInterpreterConfig *main_config,
start_buf = buf; start_buf = buf;
if (main_config->module_search_path_env) { if (main_config->module_search_path_env) {
if (wcscpy_s(buf, bufsz - (buf - start_buf), main_config->module_search_path_env)) { if (wcscpy_s(buf, bufsz - (buf - start_buf),
main_config->module_search_path_env)) {
return INIT_ERR_BUFFER_OVERFLOW(); return INIT_ERR_BUFFER_OVERFLOW();
} }
buf = wcschr(buf, L'\0'); buf = wcschr(buf, L'\0');
...@@ -1214,7 +1221,7 @@ Py_GetProgramFullPath(void) ...@@ -1214,7 +1221,7 @@ Py_GetProgramFullPath(void)
static int python3_checked = 0; static int python3_checked = 0;
static HANDLE hPython3; static HANDLE hPython3;
int int
_Py_CheckPython3() _Py_CheckPython3(void)
{ {
wchar_t py3path[MAXPATHLEN+1]; wchar_t py3path[MAXPATHLEN+1];
wchar_t *s; wchar_t *s;
......
...@@ -1273,8 +1273,6 @@ Py_FinalizeEx(void) ...@@ -1273,8 +1273,6 @@ Py_FinalizeEx(void)
call_ll_exitfuncs(); call_ll_exitfuncs();
_PyPathConfig_Fini();
_PyRuntime_Finalize(); _PyRuntime_Finalize();
return status; return status;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment