mirror of https://github.com/python/cpython.git
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
This commit is contained in:
parent
9ac3d88827
commit
ebac19dad6
|
@ -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,
|
||||||
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)
|
||||||
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)
|
||||||
* 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)
|
||||||
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
|
||||||
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,
|
||||||
#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,
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
call_ll_exitfuncs();
|
call_ll_exitfuncs();
|
||||||
|
|
||||||
_PyPathConfig_Fini();
|
|
||||||
|
|
||||||
_PyRuntime_Finalize();
|
_PyRuntime_Finalize();
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue