Commit 2c8ddcf4 authored by Victor Stinner's avatar Victor Stinner Committed by GitHub

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.
parent 9e4994d4
...@@ -1344,7 +1344,7 @@ pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config, ...@@ -1344,7 +1344,7 @@ pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config,
* See the documentation of the PYTHONCOERCECLOCALE setting for more * See the documentation of the PYTHONCOERCECLOCALE setting for more
* details. * details.
*/ */
if (config->coerce_c_locale == 1 && !locale_coerced) { if (config->coerce_c_locale && !locale_coerced) {
locale_coerced = 1; locale_coerced = 1;
_Py_CoerceLegacyLocale(config); _Py_CoerceLegacyLocale(config);
encoding_changed = 1; encoding_changed = 1;
...@@ -1369,6 +1369,7 @@ pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config, ...@@ -1369,6 +1369,7 @@ pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config,
/* Reset the configuration before reading again the configuration, /* Reset the configuration before reading again the configuration,
just keep UTF-8 Mode value. */ just keep UTF-8 Mode value. */
int new_utf8_mode = config->utf8_mode; int new_utf8_mode = config->utf8_mode;
int new_coerce_c_locale = config->coerce_c_locale;
if (_PyCoreConfig_Copy(config, &save_config) < 0) { if (_PyCoreConfig_Copy(config, &save_config) < 0) {
pymain->err = _Py_INIT_NO_MEMORY(); pymain->err = _Py_INIT_NO_MEMORY();
goto done; goto done;
...@@ -1376,6 +1377,7 @@ pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config, ...@@ -1376,6 +1377,7 @@ pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config,
pymain_clear_cmdline(pymain, cmdline); pymain_clear_cmdline(pymain, cmdline);
memset(cmdline, 0, sizeof(*cmdline)); memset(cmdline, 0, sizeof(*cmdline));
config->utf8_mode = new_utf8_mode; config->utf8_mode = new_utf8_mode;
config->coerce_c_locale = new_coerce_c_locale;
/* The encoding changed: read again the configuration /* The encoding changed: read again the configuration
with the new encoding */ with the new encoding */
......
...@@ -671,16 +671,18 @@ config_read_env_vars(_PyCoreConfig *config) ...@@ -671,16 +671,18 @@ config_read_env_vars(_PyCoreConfig *config)
config->malloc_stats = 1; config->malloc_stats = 1;
} }
if (config->coerce_c_locale < 0) { const char *env = _PyCoreConfig_GetEnv(config, "PYTHONCOERCECLOCALE");
const char *env = _PyCoreConfig_GetEnv(config, "PYTHONCOERCECLOCALE"); if (env) {
if (env) { if (strcmp(env, "0") == 0) {
if (strcmp(env, "0") == 0) { if (config->coerce_c_locale < 0) {
config->coerce_c_locale = 0; config->coerce_c_locale = 0;
} }
else if (strcmp(env, "warn") == 0) { }
config->coerce_c_locale_warn = 1; else if (strcmp(env, "warn") == 0) {
} config->coerce_c_locale_warn = 1;
else { }
else {
if (config->coerce_c_locale < 0) {
config->coerce_c_locale = 1; config->coerce_c_locale = 1;
} }
} }
......
...@@ -659,10 +659,6 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p, ...@@ -659,10 +659,6 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p,
_PyRuntime.finalizing = NULL; _PyRuntime.finalizing = NULL;
#ifndef MS_WINDOWS #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); _emit_stderr_warning_for_legacy_locale(core_config);
#endif #endif
...@@ -815,6 +811,12 @@ _Py_InitializeCore(PyInterpreterState **interp_p, ...@@ -815,6 +811,12 @@ _Py_InitializeCore(PyInterpreterState **interp_p,
(and the input configuration is read only). */ (and the input configuration is read only). */
_PyCoreConfig config = _PyCoreConfig_INIT; _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); _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
if (_PyCoreConfig_Copy(&config, src_config) >= 0) { if (_PyCoreConfig_Copy(&config, src_config) >= 0) {
err = _PyCoreConfig_Read(&config); err = _PyCoreConfig_Read(&config);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment