From 2c8ddcf4f14f3e4c87a6fe6678ab5ad09130c6ab Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 29 Aug 2018 00:16:53 +0200 Subject: bpo-34485: Fix _Py_InitializeCore() for C locale coercion (GH-8979) * _Py_InitializeCore() now sets the LC_CTYPE locale to the user preferred locale before checking if the C locale should be coerced or not in _PyCoreConfig_Read(). * Fix pymain_read_conf(): remember if the C locale has been coerced when the configuration should be read again if the encoding has changed. --- Modules/main.c | 4 +++- Python/coreconfig.c | 18 ++++++++++-------- Python/pylifecycle.c | 10 ++++++---- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/Modules/main.c b/Modules/main.c index 992d720..82e0093 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -1344,7 +1344,7 @@ pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config, * See the documentation of the PYTHONCOERCECLOCALE setting for more * details. */ - if (config->coerce_c_locale == 1 && !locale_coerced) { + if (config->coerce_c_locale && !locale_coerced) { locale_coerced = 1; _Py_CoerceLegacyLocale(config); encoding_changed = 1; @@ -1369,6 +1369,7 @@ pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config, /* Reset the configuration before reading again the configuration, just keep UTF-8 Mode value. */ int new_utf8_mode = config->utf8_mode; + int new_coerce_c_locale = config->coerce_c_locale; if (_PyCoreConfig_Copy(config, &save_config) < 0) { pymain->err = _Py_INIT_NO_MEMORY(); goto done; @@ -1376,6 +1377,7 @@ pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config, pymain_clear_cmdline(pymain, cmdline); memset(cmdline, 0, sizeof(*cmdline)); config->utf8_mode = new_utf8_mode; + config->coerce_c_locale = new_coerce_c_locale; /* The encoding changed: read again the configuration with the new encoding */ diff --git a/Python/coreconfig.c b/Python/coreconfig.c index d08d75b..8724681 100644 --- a/Python/coreconfig.c +++ b/Python/coreconfig.c @@ -671,16 +671,18 @@ config_read_env_vars(_PyCoreConfig *config) config->malloc_stats = 1; } - if (config->coerce_c_locale < 0) { - const char *env = _PyCoreConfig_GetEnv(config, "PYTHONCOERCECLOCALE"); - if (env) { - if (strcmp(env, "0") == 0) { + const char *env = _PyCoreConfig_GetEnv(config, "PYTHONCOERCECLOCALE"); + if (env) { + if (strcmp(env, "0") == 0) { + if (config->coerce_c_locale < 0) { config->coerce_c_locale = 0; } - else if (strcmp(env, "warn") == 0) { - config->coerce_c_locale_warn = 1; - } - else { + } + else if (strcmp(env, "warn") == 0) { + config->coerce_c_locale_warn = 1; + } + else { + if (config->coerce_c_locale < 0) { config->coerce_c_locale = 1; } } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 29711df..4d248ed 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -659,10 +659,6 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p, _PyRuntime.finalizing = NULL; #ifndef MS_WINDOWS - /* Set up the LC_CTYPE locale, so we can obtain - the locale's charset without having to switch - locales. */ - _Py_SetLocaleFromEnv(LC_CTYPE); _emit_stderr_warning_for_legacy_locale(core_config); #endif @@ -815,6 +811,12 @@ _Py_InitializeCore(PyInterpreterState **interp_p, (and the input configuration is read only). */ _PyCoreConfig config = _PyCoreConfig_INIT; +#ifndef MS_WINDOWS + /* Set up the LC_CTYPE locale, so we can obtain the locale's charset + without having to switch locales. */ + _Py_SetLocaleFromEnv(LC_CTYPE); +#endif + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); if (_PyCoreConfig_Copy(&config, src_config) >= 0) { err = _PyCoreConfig_Read(&config); -- cgit v0.12