Skip to content

Commit 77f5515

Browse files
Remove optimistic allocation in locale.strxfrm()
On modern systems, the result of wcsxfrm() is much larger the size of the input string (from 4+2*n on Windows to 4+5*n on Linux for simple ASCII strings), so optimistic allocation of the buffer of the same size never works.
1 parent ae8b7d7 commit 77f5515

1 file changed

Lines changed: 9 additions & 19 deletions

File tree

Modules/_localemodule.c

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -409,33 +409,23 @@ _locale_strxfrm_impl(PyObject *module, PyObject *str)
409409
}
410410

411411
/* assume no change in size, first */
412-
n1 = n1 + 1;
413-
buf = PyMem_New(wchar_t, n1);
412+
errno = 0;
413+
n2 = wcsxfrm(NULL, s, 0);
414+
if (errno && errno != ERANGE) {
415+
PyErr_SetFromErrno(PyExc_OSError);
416+
goto exit;
417+
}
418+
buf = PyMem_New(wchar_t, n2+1);
414419
if (!buf) {
415420
PyErr_NoMemory();
416421
goto exit;
417422
}
418423
errno = 0;
419-
n2 = wcsxfrm(buf, s, n1);
420-
if (errno && errno != ERANGE) {
424+
n2 = wcsxfrm(buf, s, n2+1);
425+
if (errno) {
421426
PyErr_SetFromErrno(PyExc_OSError);
422427
goto exit;
423428
}
424-
if (n2 >= (size_t)n1) {
425-
/* more space needed */
426-
wchar_t * new_buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
427-
if (!new_buf) {
428-
PyErr_NoMemory();
429-
goto exit;
430-
}
431-
buf = new_buf;
432-
errno = 0;
433-
n2 = wcsxfrm(buf, s, n2+1);
434-
if (errno) {
435-
PyErr_SetFromErrno(PyExc_OSError);
436-
goto exit;
437-
}
438-
}
439429
result = PyUnicode_FromWideChar(buf, n2);
440430
exit:
441431
PyMem_Free(buf);

0 commit comments

Comments
 (0)