[3.13] gh-137273: Fix debug assertion failure in locale.setlocale() on Windows (GH-137300) (GH-137306)
Some checks are pending
Tests / Check if generated files are up to date (push) Blocked by required conditions
Tests / Change detection (push) Waiting to run
Tests / Docs (push) Blocked by required conditions
Tests / (push) Blocked by required conditions
Tests / Windows MSI (push) Blocked by required conditions
Tests / Check if the ABI has changed (push) Blocked by required conditions
Tests / Check if Autoconf files are up to date (push) Blocked by required conditions
Tests / Sanitizers (push) Blocked by required conditions
Tests / Ubuntu SSL tests with OpenSSL (push) Blocked by required conditions
Tests / WASI (push) Blocked by required conditions
Tests / Hypothesis tests on Ubuntu (push) Blocked by required conditions
Tests / Address sanitizer (push) Blocked by required conditions
Tests / CIFuzz (push) Blocked by required conditions
Tests / All required checks pass (push) Blocked by required conditions
Lint / lint (push) Waiting to run

It happened when there were at least 16 characters after dot in the
locale name.
(cherry picked from commit 718e0c89ba)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
Miss Islington (bot) 2025-08-01 17:06:16 +02:00 committed by GitHub
parent 6a217cef27
commit a32bd11cb0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 97 additions and 21 deletions

View file

@ -87,6 +87,41 @@ copy_grouping(const char* s)
return result;
}
#if defined(MS_WINDOWS)
// 16 is the number of elements in the szCodePage field
// of the __crt_locale_strings structure.
#define MAX_CP_LEN 15
static int
check_locale_name(const char *locale, const char *end)
{
size_t len = end ? (size_t)(end - locale) : strlen(locale);
const char *dot = memchr(locale, '.', len);
if (dot && locale + len - dot - 1 > MAX_CP_LEN) {
return -1;
}
return 0;
}
static int
check_locale_name_all(const char *locale)
{
const char *start = locale;
while (1) {
const char *end = strchr(start, ';');
if (check_locale_name(start, end) < 0) {
return -1;
}
if (end == NULL) {
break;
}
start = end + 1;
}
return 0;
}
#endif
/*[clinic input]
_locale.setlocale
@ -111,6 +146,18 @@ _locale_setlocale_impl(PyObject *module, int category, const char *locale)
"invalid locale category");
return NULL;
}
if (locale) {
if ((category == LC_ALL
? check_locale_name_all(locale)
: check_locale_name(locale, NULL)) < 0)
{
/* Debug assertion failure on Windows.
* _Py_BEGIN_SUPPRESS_IPH/_Py_END_SUPPRESS_IPH do not help. */
PyErr_SetString(get_locale_state(module)->Error,
"unsupported locale setting");
return NULL;
}
}
#endif
if (locale) {