mirror of
https://github.com/python/cpython.git
synced 2025-08-31 14:07:50 +00:00
gh-106844: Fix issues in _winapi.LCMapStringEx (GH-107832)
* Strings with length from 2**31-1 to 2**32-2 always caused MemoryError, it doesn't matter how much memory is available. * Strings with length exactly 2**32-1 caused OSError. * Strings longer than 2**32-1 characters were truncated due to integer overflow bug. * Strings containing the null character were truncated at the first null character. Now strings longer than 2**31-1 characters caused OverflowError and the null character is allowed.
This commit is contained in:
parent
a39f0a3506
commit
04cc01453d
4 changed files with 32 additions and 16 deletions
|
@ -1539,40 +1539,56 @@ _winapi.LCMapStringEx
|
|||
|
||||
locale: LPCWSTR
|
||||
flags: DWORD
|
||||
src: LPCWSTR
|
||||
src: unicode
|
||||
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_winapi_LCMapStringEx_impl(PyObject *module, LPCWSTR locale, DWORD flags,
|
||||
LPCWSTR src)
|
||||
/*[clinic end generated code: output=cf4713d80e2b47c9 input=9fe26f95d5ab0001]*/
|
||||
PyObject *src)
|
||||
/*[clinic end generated code: output=b90e6b26e028ff0a input=3e3dcd9b8164012f]*/
|
||||
{
|
||||
if (flags & (LCMAP_SORTHANDLE | LCMAP_HASH | LCMAP_BYTEREV |
|
||||
LCMAP_SORTKEY)) {
|
||||
return PyErr_Format(PyExc_ValueError, "unsupported flags");
|
||||
}
|
||||
|
||||
int dest_size = LCMapStringEx(locale, flags, src, -1, NULL, 0,
|
||||
Py_ssize_t src_size;
|
||||
wchar_t *src_ = PyUnicode_AsWideCharString(src, &src_size);
|
||||
if (!src_) {
|
||||
return NULL;
|
||||
}
|
||||
if (src_size > INT_MAX) {
|
||||
PyMem_Free(src_);
|
||||
PyErr_SetString(PyExc_OverflowError, "input string is too long");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int dest_size = LCMapStringEx(locale, flags, src_, (int)src_size, NULL, 0,
|
||||
NULL, NULL, 0);
|
||||
if (dest_size == 0) {
|
||||
return PyErr_SetFromWindowsErr(0);
|
||||
if (dest_size <= 0) {
|
||||
DWORD error = GetLastError();
|
||||
PyMem_Free(src_);
|
||||
return PyErr_SetFromWindowsErr(error);
|
||||
}
|
||||
|
||||
wchar_t* dest = PyMem_NEW(wchar_t, dest_size);
|
||||
if (dest == NULL) {
|
||||
PyMem_Free(src_);
|
||||
return PyErr_NoMemory();
|
||||
}
|
||||
|
||||
int nmapped = LCMapStringEx(locale, flags, src, -1, dest, dest_size,
|
||||
int nmapped = LCMapStringEx(locale, flags, src_, (int)src_size, dest, dest_size,
|
||||
NULL, NULL, 0);
|
||||
if (nmapped == 0) {
|
||||
if (nmapped <= 0) {
|
||||
DWORD error = GetLastError();
|
||||
PyMem_Free(src_);
|
||||
PyMem_DEL(dest);
|
||||
return PyErr_SetFromWindowsErr(error);
|
||||
}
|
||||
|
||||
PyObject *ret = PyUnicode_FromWideChar(dest, dest_size - 1);
|
||||
PyMem_Free(src_);
|
||||
PyObject *ret = PyUnicode_FromWideChar(dest, nmapped);
|
||||
PyMem_DEL(dest);
|
||||
|
||||
return ret;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue