diff options
author | Victor Stinner <vstinner@redhat.com> | 2018-07-21 00:06:16 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-21 00:06:16 (GMT) |
commit | b1147e43daeb3c51a63056b489e8d868404d4e22 (patch) | |
tree | c5716fcfca0f90abbc21b291cd51b0ae022759c4 /Modules/main.c | |
parent | 94487d45707772723ef19e86700a40a12743baa1 (diff) | |
download | cpython-b1147e43daeb3c51a63056b489e8d868404d4e22.zip cpython-b1147e43daeb3c51a63056b489e8d868404d4e22.tar.gz cpython-b1147e43daeb3c51a63056b489e8d868404d4e22.tar.bz2 |
bpo-34170: Rework _PyCoreConfig_Read() to avoid side effect (GH-8353)
Rework _PyCoreConfig_Read() function which *reads* core configuration
to not *modify* the path configuration.
A new _PyCoreConfig_SetPathConfig() function now recreates the path
configuration from the core configuration. This function is now
called very late in _Py_InitializeCore(), just before calling
initimport().
Changes:
* Add _PyCoreConfig.dll_path
* Py_SetPath() now fails with a fatal python error on memory
allocation failure.
* Rename _PyPathConfig_Calculate() to _PyPathConfig_Calculate_impl()
* Replace _PyPathConfig_Init() with _PyPathConfig_Calculate(): the
function now requires a _PyPathConfig
* Add _PyPathConfig_SetGlobal() to set the _Py_path_config global
variable.
* Add _PyCoreConfig_InitPathConfig(): compute the path configuration
* Add _PyCoreConfig_SetPathConfig(): set path configuration from core
configuration
* Rename wstrlist_append() to _Py_wstrlist_append()
* _Py_wstrlist_append() now handles integer overflow.
Diffstat (limited to 'Modules/main.c')
-rw-r--r-- | Modules/main.c | 139 |
1 files changed, 27 insertions, 112 deletions
diff --git a/Modules/main.c b/Modules/main.c index 1ff9855..5166e74 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -650,7 +650,7 @@ pymain_free_raw(_PyMain *pymain) configuration options set before Py_Initialize() which should remain valid after Py_Finalize(), since Py_Initialize()-Py_Finalize() can be called multiple times. */ - _PyPathConfig_Clear(&_Py_path_config); + _PyPathConfig_ClearGlobal(); pymain_clear_config(pymain); @@ -701,9 +701,13 @@ error: } -static _PyInitError -wstrlist_append(int *len, wchar_t ***list, const wchar_t *str) +_PyInitError +_Py_wstrlist_append(int *len, wchar_t ***list, const wchar_t *str) { + if (*len == INT_MAX) { + /* len+1 would overflow */ + return _Py_INIT_NO_MEMORY(); + } wchar_t *str2 = _PyMem_RawWcsdup(str); if (str2 == NULL) { return _Py_INIT_NO_MEMORY(); @@ -725,7 +729,7 @@ wstrlist_append(int *len, wchar_t ***list, const wchar_t *str) static int pymain_wstrlist_append(_PyMain *pymain, int *len, wchar_t ***list, const wchar_t *str) { - _PyInitError err = wstrlist_append(len, list, str); + _PyInitError err = _Py_wstrlist_append(len, list, str); if (_Py_INIT_FAILED(err)) { pymain->err = err; return -1; @@ -972,9 +976,9 @@ static _PyInitError config_add_warnings_optlist(_PyCoreConfig *config, int len, wchar_t **options) { for (int i = 0; i < len; i++) { - _PyInitError err = wstrlist_append(&config->nwarnoption, - &config->warnoptions, - options[i]); + _PyInitError err = _Py_wstrlist_append(&config->nwarnoption, + &config->warnoptions, + options[i]); if (_Py_INIT_FAILED(err)) { return err; } @@ -1006,9 +1010,9 @@ config_init_warnoptions(_PyCoreConfig *config, _Py_CommandLineDetails *cmdline) */ if (config->dev_mode) { - err = wstrlist_append(&config->nwarnoption, - &config->warnoptions, - L"default"); + err = _Py_wstrlist_append(&config->nwarnoption, + &config->warnoptions, + L"default"); if (_Py_INIT_FAILED(err)) { return err; } @@ -1040,9 +1044,9 @@ config_init_warnoptions(_PyCoreConfig *config, _Py_CommandLineDetails *cmdline) else { filter = L"default::BytesWarning"; } - err = wstrlist_append(&config->nwarnoption, - &config->warnoptions, - filter); + err = _Py_wstrlist_append(&config->nwarnoption, + &config->warnoptions, + filter); if (_Py_INIT_FAILED(err)) { return err; } @@ -1077,9 +1081,9 @@ cmdline_init_env_warnoptions(_Py_CommandLineDetails *cmdline) warning != NULL; warning = WCSTOK(NULL, L",", &context)) { - _PyInitError err = wstrlist_append(&cmdline->nenv_warnoption, - &cmdline->env_warnoptions, - warning); + _PyInitError err = _Py_wstrlist_append(&cmdline->nenv_warnoption, + &cmdline->env_warnoptions, + warning); if (_Py_INIT_FAILED(err)) { PyMem_RawFree(env); return err; @@ -2099,101 +2103,6 @@ config_init_locale(_PyCoreConfig *config) } -static _PyInitError -config_init_module_search_paths(_PyCoreConfig *config) -{ - assert(config->module_search_paths == NULL); - assert(config->nmodule_search_path < 0); - - config->nmodule_search_path = 0; - - const wchar_t *sys_path = Py_GetPath(); - const wchar_t delim = DELIM; - const wchar_t *p = sys_path; - while (1) { - p = wcschr(sys_path, delim); - if (p == NULL) { - p = sys_path + wcslen(sys_path); /* End of string */ - } - - size_t path_len = (p - sys_path); - wchar_t *path = PyMem_RawMalloc((path_len + 1) * sizeof(wchar_t)); - if (path == NULL) { - return _Py_INIT_NO_MEMORY(); - } - memcpy(path, sys_path, path_len * sizeof(wchar_t)); - path[path_len] = L'\0'; - - _PyInitError err = wstrlist_append(&config->nmodule_search_path, - &config->module_search_paths, - path); - PyMem_RawFree(path); - if (_Py_INIT_FAILED(err)) { - return err; - } - - if (*p == '\0') { - break; - } - sys_path = p + 1; - } - return _Py_INIT_OK(); -} - - -static _PyInitError -config_init_path_config(_PyCoreConfig *config) -{ - _PyInitError err = _PyPathConfig_Init(config); - if (_Py_INIT_FAILED(err)) { - return err; - } - - if (config->nmodule_search_path < 0) { - err = config_init_module_search_paths(config); - if (_Py_INIT_FAILED(err)) { - return err; - } - } - - if (config->executable == NULL) { - config->executable = _PyMem_RawWcsdup(Py_GetProgramFullPath()); - if (config->executable == NULL) { - return _Py_INIT_NO_MEMORY(); - } - } - - if (config->prefix == NULL) { - config->prefix = _PyMem_RawWcsdup(Py_GetPrefix()); - if (config->prefix == NULL) { - return _Py_INIT_NO_MEMORY(); - } - } - - if (config->exec_prefix == NULL) { - config->exec_prefix = _PyMem_RawWcsdup(Py_GetExecPrefix()); - if (config->exec_prefix == NULL) { - return _Py_INIT_NO_MEMORY(); - } - } - - if (config->base_prefix == NULL) { - config->base_prefix = _PyMem_RawWcsdup(config->prefix); - if (config->base_prefix == NULL) { - return _Py_INIT_NO_MEMORY(); - } - } - - if (config->base_exec_prefix == NULL) { - config->base_exec_prefix = _PyMem_RawWcsdup(config->exec_prefix); - if (config->base_exec_prefix == NULL) { - return _Py_INIT_NO_MEMORY(); - } - } - - return _Py_INIT_OK(); -} - /* Read configuration settings from standard locations * * This function doesn't make any changes to the interpreter state - it @@ -2252,7 +2161,7 @@ _PyCoreConfig_Read(_PyCoreConfig *config) } if (!config->_disable_importlib) { - err = config_init_path_config(config); + err = _PyCoreConfig_InitPathConfig(config); if (_Py_INIT_FAILED(err)) { return err; } @@ -2294,6 +2203,9 @@ _PyCoreConfig_Clear(_PyCoreConfig *config) CLEAR(config->prefix); CLEAR(config->base_prefix); CLEAR(config->exec_prefix); +#ifdef MS_WINDOWS + CLEAR(config->dll_path); +#endif CLEAR(config->base_exec_prefix); #undef CLEAR #undef CLEAR_WSTRLIST @@ -2356,6 +2268,9 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) COPY_STR_ATTR(prefix); COPY_STR_ATTR(base_prefix); COPY_STR_ATTR(exec_prefix); +#ifdef MS_WINDOWS + COPY_STR_ATTR(dll_path); +#endif COPY_STR_ATTR(base_exec_prefix); #undef COPY_ATTR |