bpo-34170: Rework _PyCoreConfig_Read() to avoid side effect (GH-8353) · python/cpython@b1147e4
@@ -650,7 +650,7 @@ pymain_free_raw(_PyMain *pymain)
650650 configuration options set before Py_Initialize() which should
651651 remain valid after Py_Finalize(), since
652652 Py_Initialize()-Py_Finalize() can be called multiple times. */
653-_PyPathConfig_Clear(&_Py_path_config);
653+_PyPathConfig_ClearGlobal();
654654655655pymain_clear_config(pymain);
656656@@ -701,9 +701,13 @@ pymain_run_main_from_importer(_PyMain *pymain)
701701}
702702703703704-static _PyInitError
705-wstrlist_append(int *len, wchar_t ***list, const wchar_t *str)
704+_PyInitError
705+_Py_wstrlist_append(int *len, wchar_t ***list, const wchar_t *str)
706706{
707+if (*len == INT_MAX) {
708+/* len+1 would overflow */
709+return _Py_INIT_NO_MEMORY();
710+ }
707711wchar_t *str2 = _PyMem_RawWcsdup(str);
708712if (str2 == NULL) {
709713return _Py_INIT_NO_MEMORY();
@@ -725,7 +729,7 @@ wstrlist_append(int *len, wchar_t ***list, const wchar_t *str)
725729static int
726730pymain_wstrlist_append(_PyMain *pymain, int *len, wchar_t ***list, const wchar_t *str)
727731{
728-_PyInitError err = wstrlist_append(len, list, str);
732+_PyInitError err = _Py_wstrlist_append(len, list, str);
729733if (_Py_INIT_FAILED(err)) {
730734pymain->err = err;
731735return -1;
@@ -972,9 +976,9 @@ static _PyInitError
972976config_add_warnings_optlist(_PyCoreConfig *config, int len, wchar_t **options)
973977{
974978for (int i = 0; i < len; i++) {
975-_PyInitError err = wstrlist_append(&config->nwarnoption,
976-&config->warnoptions,
977-options[i]);
979+_PyInitError err = _Py_wstrlist_append(&config->nwarnoption,
980+ &config->warnoptions,
981+ options[i]);
978982if (_Py_INIT_FAILED(err)) {
979983return err;
980984 }
@@ -1006,9 +1010,9 @@ config_init_warnoptions(_PyCoreConfig *config, _Py_CommandLineDetails *cmdline)
10061010 */
1007101110081012if (config->dev_mode) {
1009-err = wstrlist_append(&config->nwarnoption,
1010-&config->warnoptions,
1011-L"default");
1013+err = _Py_wstrlist_append(&config->nwarnoption,
1014+ &config->warnoptions,
1015+ L"default");
10121016if (_Py_INIT_FAILED(err)) {
10131017return err;
10141018 }
@@ -1040,9 +1044,9 @@ config_init_warnoptions(_PyCoreConfig *config, _Py_CommandLineDetails *cmdline)
10401044else {
10411045filter = L"default::BytesWarning";
10421046 }
1043-err = wstrlist_append(&config->nwarnoption,
1044-&config->warnoptions,
1045-filter);
1047+err = _Py_wstrlist_append(&config->nwarnoption,
1048+ &config->warnoptions,
1049+ filter);
10461050if (_Py_INIT_FAILED(err)) {
10471051return err;
10481052 }
@@ -1077,9 +1081,9 @@ cmdline_init_env_warnoptions(_Py_CommandLineDetails *cmdline)
10771081warning != NULL;
10781082warning = WCSTOK(NULL, L",", &context))
10791083 {
1080-_PyInitError err = wstrlist_append(&cmdline->nenv_warnoption,
1081-&cmdline->env_warnoptions,
1082-warning);
1084+_PyInitError err = _Py_wstrlist_append(&cmdline->nenv_warnoption,
1085+ &cmdline->env_warnoptions,
1086+ warning);
10831087if (_Py_INIT_FAILED(err)) {
10841088PyMem_RawFree(env);
10851089return err;
@@ -2099,101 +2103,6 @@ config_init_locale(_PyCoreConfig *config)
20992103}
21002104210121052102-static _PyInitError
2103-config_init_module_search_paths(_PyCoreConfig *config)
2104-{
2105-assert(config->module_search_paths == NULL);
2106-assert(config->nmodule_search_path < 0);
2107-2108-config->nmodule_search_path = 0;
2109-2110-const wchar_t *sys_path = Py_GetPath();
2111-const wchar_t delim = DELIM;
2112-const wchar_t *p = sys_path;
2113-while (1) {
2114-p = wcschr(sys_path, delim);
2115-if (p == NULL) {
2116-p = sys_path + wcslen(sys_path); /* End of string */
2117- }
2118-2119-size_t path_len = (p - sys_path);
2120-wchar_t *path = PyMem_RawMalloc((path_len + 1) * sizeof(wchar_t));
2121-if (path == NULL) {
2122-return _Py_INIT_NO_MEMORY();
2123- }
2124-memcpy(path, sys_path, path_len * sizeof(wchar_t));
2125-path[path_len] = L'\0';
2126-2127-_PyInitError err = wstrlist_append(&config->nmodule_search_path,
2128-&config->module_search_paths,
2129-path);
2130-PyMem_RawFree(path);
2131-if (_Py_INIT_FAILED(err)) {
2132-return err;
2133- }
2134-2135-if (*p == '\0') {
2136-break;
2137- }
2138-sys_path = p + 1;
2139- }
2140-return _Py_INIT_OK();
2141-}
2142-2143-2144-static _PyInitError
2145-config_init_path_config(_PyCoreConfig *config)
2146-{
2147-_PyInitError err = _PyPathConfig_Init(config);
2148-if (_Py_INIT_FAILED(err)) {
2149-return err;
2150- }
2151-2152-if (config->nmodule_search_path < 0) {
2153-err = config_init_module_search_paths(config);
2154-if (_Py_INIT_FAILED(err)) {
2155-return err;
2156- }
2157- }
2158-2159-if (config->executable == NULL) {
2160-config->executable = _PyMem_RawWcsdup(Py_GetProgramFullPath());
2161-if (config->executable == NULL) {
2162-return _Py_INIT_NO_MEMORY();
2163- }
2164- }
2165-2166-if (config->prefix == NULL) {
2167-config->prefix = _PyMem_RawWcsdup(Py_GetPrefix());
2168-if (config->prefix == NULL) {
2169-return _Py_INIT_NO_MEMORY();
2170- }
2171- }
2172-2173-if (config->exec_prefix == NULL) {
2174-config->exec_prefix = _PyMem_RawWcsdup(Py_GetExecPrefix());
2175-if (config->exec_prefix == NULL) {
2176-return _Py_INIT_NO_MEMORY();
2177- }
2178- }
2179-2180-if (config->base_prefix == NULL) {
2181-config->base_prefix = _PyMem_RawWcsdup(config->prefix);
2182-if (config->base_prefix == NULL) {
2183-return _Py_INIT_NO_MEMORY();
2184- }
2185- }
2186-2187-if (config->base_exec_prefix == NULL) {
2188-config->base_exec_prefix = _PyMem_RawWcsdup(config->exec_prefix);
2189-if (config->base_exec_prefix == NULL) {
2190-return _Py_INIT_NO_MEMORY();
2191- }
2192- }
2193-2194-return _Py_INIT_OK();
2195-}
2196-21972106/* Read configuration settings from standard locations
21982107 *
21992108 * This function doesn't make any changes to the interpreter state - it
@@ -2252,7 +2161,7 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
22522161 }
2253216222542163if (!config->_disable_importlib) {
2255-err = config_init_path_config(config);
2164+err = _PyCoreConfig_InitPathConfig(config);
22562165if (_Py_INIT_FAILED(err)) {
22572166return err;
22582167 }
@@ -2294,6 +2203,9 @@ _PyCoreConfig_Clear(_PyCoreConfig *config)
22942203CLEAR(config->prefix);
22952204CLEAR(config->base_prefix);
22962205CLEAR(config->exec_prefix);
2206+#ifdef MS_WINDOWS
2207+CLEAR(config->dll_path);
2208+#endif
22972209CLEAR(config->base_exec_prefix);
22982210#undef CLEAR
22992211#undef CLEAR_WSTRLIST
@@ -2356,6 +2268,9 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
23562268COPY_STR_ATTR(prefix);
23572269COPY_STR_ATTR(base_prefix);
23582270COPY_STR_ATTR(exec_prefix);
2271+#ifdef MS_WINDOWS
2272+COPY_STR_ATTR(dll_path);
2273+#endif
23592274COPY_STR_ATTR(base_exec_prefix);
2360227523612276#undef COPY_ATTR