diff --git a/Misc/NEWS.d/next/Library/2026-07-19-21-30-00.gh-issue-154176.strxfrm.rst b/Misc/NEWS.d/next/Library/2026-07-19-21-30-00.gh-issue-154176.strxfrm.rst new file mode 100644 index 00000000000000..9ffa5828000113 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-19-21-30-00.gh-issue-154176.strxfrm.rst @@ -0,0 +1,2 @@ +Fix a crash in :func:`locale.strxfrm` on DragonFly BSD, +whose ``wcsxfrm()`` does not support the zero size. diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c index 0f71358a180dd2..20783dc00f90d3 100644 --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -443,6 +443,7 @@ _locale_strxfrm_impl(PyObject *module, PyObject *str) { Py_ssize_t n1; wchar_t *s = NULL, *buf = NULL; + wchar_t dummy[1]; size_t n2; PyObject *result = NULL; @@ -456,7 +457,9 @@ _locale_strxfrm_impl(PyObject *module, PyObject *str) } errno = 0; - n2 = wcsxfrm(NULL, s, 0); + /* Query the size with a real one-element buffer: DragonFly BSD's + wcsxfrm() crashes when the destination is NULL or the size is 0. */ + n2 = wcsxfrm(dummy, s, 1); if (errno && errno != ERANGE) { PyErr_SetFromErrno(PyExc_OSError); goto exit;