]> granicus.if.org Git - python/commitdiff
bpo-32030: Don't call _PyPathConfig_Fini() in Py_FinalizeEx() (#4667)
authorVictor Stinner <victor.stinner@gmail.com>
Fri, 1 Dec 2017 19:09:52 +0000 (20:09 +0100)
committerGitHub <noreply@github.com>
Fri, 1 Dec 2017 19:09:52 +0000 (20:09 +0100)
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

Include/pylifecycle.h
Modules/getpath.c
Modules/main.c
PC/getpathp.c
Python/pylifecycle.c

index d32c98b69856884c70774365a944b0520acd1e6d..3db88326aeeca6eac28c9ca60389c2e02d77a91c 100644 (file)
@@ -109,7 +109,7 @@ PyAPI_FUNC(void) _PyPathConfig_Fini(void);
 #endif
 PyAPI_FUNC(void)      Py_SetPath(const wchar_t *);
 #ifdef MS_WINDOWS
-int _Py_CheckPython3();
+int _Py_CheckPython3(void);
 #endif
 
 /* In their own files */
index 183717d817173ea4aefa8277e41db7c61cbd58d9..235badab230bd162e85b5340dfa998adef27c615 100644 (file)
@@ -625,11 +625,13 @@ calculate_program_full_path(const _PyMainInterpreterConfig *main_config,
     else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) &&
             execpath[0] == SEP)
     {
-        size_t r = mbstowcs(program_full_path, execpath, MAXPATHLEN+1);
-        if (r == (size_t)-1 || r > MAXPATHLEN) {
-            /* Could not convert execpath, or it's too long. */
-            program_full_path[0] = '\0';
+        size_t len;
+        wchar_t *path = Py_DecodeLocale(execpath, &len);
+        if (path == NULL) {
+            return DECODE_LOCALE_ERR("executable path", len);
         }
+        wcsncpy(program_full_path, path, MAXPATHLEN);
+        PyMem_RawFree(path);
     }
 #endif /* __APPLE__ */
     else if (calculate->path_env) {
index caec97f8642385a979cfc0351d4891e4b0b104aa..4659c5d670b78a6ea245fd94bb7495078f66f9e1 100644 (file)
@@ -888,15 +888,12 @@ config_get_program_name(_PyMainInterpreterConfig *config)
        See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
        script. */
     if ((p = Py_GETENV("PYTHONEXECUTABLE")) && *p != '\0') {
-        wchar_t* buffer;
-        size_t len = strlen(p) + 1;
-
-        buffer = PyMem_RawMalloc(len * sizeof(wchar_t));
-        if (buffer == NULL) {
-            return _Py_INIT_NO_MEMORY();
+        size_t len;
+        wchar_t* program_name = Py_DecodeLocale(p, &len);
+        if (program_name == NULL) {
+            return SET_DECODE_ERROR("PYTHONEXECUTABLE environment "
+                                    "variable", len);
         }
-
-        mbstowcs(buffer, p, len);
         pymain->config.program_name = buffer;
     }
 #ifdef WITH_NEXT_FRAMEWORK
@@ -907,11 +904,12 @@ config_get_program_name(_PyMainInterpreterConfig *config)
              * the argv0 of the stub executable
              */
             size_t len;
-            wchar_t* wbuf = Py_DecodeLocale(pyvenv_launcher, &len);
-            if (wbuf == NULL) {
-                return SET_DECODE_ERROR("__PYVENV_LAUNCHER__", len);
+            wchar_t* program_name = Py_DecodeLocale(pyvenv_launcher, &len);
+            if (program_name == NULL) {
+                return SET_DECODE_ERROR("__PYVENV_LAUNCHER__ environment "
+                                        "variable", len);
             }
-            pymain->config.program_name = wbuf;
+            pymain->config.program_name = program_name;
         }
     }
 #endif   /* WITH_NEXT_FRAMEWORK */
@@ -1666,6 +1664,14 @@ pymain_impl(_PyMain *pymain)
            other special meaning */
         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;
 }
 
index 89d37a84133622f21d45eba21c835ea770169724..f8cfd7e69783862d550db5aabb04821fb53b1f99 100644 (file)
@@ -721,12 +721,16 @@ static int
 get_pth_filename(wchar_t *spbuffer, _PyPathConfig *config)
 {
     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;
         }
     }
     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;
         }
     }
@@ -823,8 +827,10 @@ calculate_module_search_path(const _PyMainInterpreterConfig *main_config,
 #endif
     /* We only use the default relative PYTHONPATH if we haven't
        anything better to use! */
-    int skipdefault = (main_config->module_search_path_env!=NULL || calculate->home!=NULL || \
-                       calculate->machine_path!=NULL || calculate->user_path!=NULL);
+    int skipdefault = (main_config->module_search_path_env != NULL ||
+                       calculate->home != NULL ||
+                       calculate->machine_path != NULL ||
+                       calculate->user_path != NULL);
 
     /* We need to construct a path from the following parts.
        (1) the PYTHONPATH environment variable, if set;
@@ -882,7 +888,8 @@ calculate_module_search_path(const _PyMainInterpreterConfig *main_config,
     start_buf = buf;
 
     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();
         }
         buf = wcschr(buf, L'\0');
@@ -1214,7 +1221,7 @@ Py_GetProgramFullPath(void)
 static int python3_checked = 0;
 static HANDLE hPython3;
 int
-_Py_CheckPython3()
+_Py_CheckPython3(void)
 {
     wchar_t py3path[MAXPATHLEN+1];
     wchar_t *s;
index f0a49f91fb85bf79f297350cbfe870cfd97d2a1d..a1b29f2a0eb0fd51a262db33f3d6fec6d2f60bd0 100644 (file)
@@ -1273,8 +1273,6 @@ Py_FinalizeEx(void)
 
     call_ll_exitfuncs();
 
-    _PyPathConfig_Fini();
-
     _PyRuntime_Finalize();
     return status;
 }