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();

654654655655

pymain_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+

}

707711

wchar_t *str2 = _PyMem_RawWcsdup(str);

708712

if (str2 == NULL) {

709713

return _Py_INIT_NO_MEMORY();

@@ -725,7 +729,7 @@ wstrlist_append(int *len, wchar_t ***list, const wchar_t *str)

725729

static int

726730

pymain_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);

729733

if (_Py_INIT_FAILED(err)) {

730734

pymain->err = err;

731735

return -1;

@@ -972,9 +976,9 @@ static _PyInitError

972976

config_add_warnings_optlist(_PyCoreConfig *config, int len, wchar_t **options)

973977

{

974978

for (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]);

978982

if (_Py_INIT_FAILED(err)) {

979983

return err;

980984

}

@@ -1006,9 +1010,9 @@ config_init_warnoptions(_PyCoreConfig *config, _Py_CommandLineDetails *cmdline)

10061010

*/

1007101110081012

if (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");

10121016

if (_Py_INIT_FAILED(err)) {

10131017

return err;

10141018

}

@@ -1040,9 +1044,9 @@ config_init_warnoptions(_PyCoreConfig *config, _Py_CommandLineDetails *cmdline)

10401044

else {

10411045

filter = 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);

10461050

if (_Py_INIT_FAILED(err)) {

10471051

return err;

10481052

}

@@ -1077,9 +1081,9 @@ cmdline_init_env_warnoptions(_Py_CommandLineDetails *cmdline)

10771081

warning != NULL;

10781082

warning = 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);

10831087

if (_Py_INIT_FAILED(err)) {

10841088

PyMem_RawFree(env);

10851089

return 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

}

2253216222542163

if (!config->_disable_importlib) {

2255-

err = config_init_path_config(config);

2164+

err = _PyCoreConfig_InitPathConfig(config);

22562165

if (_Py_INIT_FAILED(err)) {

22572166

return err;

22582167

}

@@ -2294,6 +2203,9 @@ _PyCoreConfig_Clear(_PyCoreConfig *config)

22942203

CLEAR(config->prefix);

22952204

CLEAR(config->base_prefix);

22962205

CLEAR(config->exec_prefix);

2206+

#ifdef MS_WINDOWS

2207+

CLEAR(config->dll_path);

2208+

#endif

22972209

CLEAR(config->base_exec_prefix);

22982210

#undef CLEAR

22992211

#undef CLEAR_WSTRLIST

@@ -2356,6 +2268,9 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)

23562268

COPY_STR_ATTR(prefix);

23572269

COPY_STR_ATTR(base_prefix);

23582270

COPY_STR_ATTR(exec_prefix);

2271+

#ifdef MS_WINDOWS

2272+

COPY_STR_ATTR(dll_path);

2273+

#endif

23592274

COPY_STR_ATTR(base_exec_prefix);

2360227523612276

#undef COPY_ATTR