mirror of https://github.com/python/cpython.git
[3.11] gh-106844: Fix issues in _winapi.LCMapStringEx (GH-107832) (GH-107875)
* 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.
Now strings longer than 2**31-1 characters caused OverflowError.
(cherry picked from commit 04cc01453d
)
This commit is contained in:
parent
4ddfb04260
commit
ec254c5dfa
|
@ -908,6 +908,7 @@ def test_path_normcase(self):
|
||||||
self._check_function(self.path.normcase)
|
self._check_function(self.path.normcase)
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
self.assertEqual(ntpath.normcase('\u03a9\u2126'), 'ωΩ')
|
self.assertEqual(ntpath.normcase('\u03a9\u2126'), 'ωΩ')
|
||||||
|
self.assertEqual(ntpath.normcase('abc\x00def'), 'abc\x00def')
|
||||||
|
|
||||||
def test_path_isabs(self):
|
def test_path_isabs(self):
|
||||||
self._check_function(self.path.isabs)
|
self._check_function(self.path.isabs)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fix integer overflow in :func:`!_winapi.LCMapStringEx` which affects :func:`ntpath.normcase`.
|
|
@ -1571,24 +1571,26 @@ _winapi_LCMapStringEx_impl(PyObject *module, PyObject *locale, DWORD flags,
|
||||||
if (!locale_) {
|
if (!locale_) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
Py_ssize_t srcLenAsSsize;
|
Py_ssize_t src_size;
|
||||||
int srcLen;
|
wchar_t *src_ = PyUnicode_AsWideCharString(src, &src_size);
|
||||||
wchar_t *src_ = PyUnicode_AsWideCharString(src, &srcLenAsSsize);
|
|
||||||
if (!src_) {
|
if (!src_) {
|
||||||
PyMem_Free(locale_);
|
PyMem_Free(locale_);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
srcLen = (int)srcLenAsSsize;
|
if (src_size > INT_MAX) {
|
||||||
if (srcLen != srcLenAsSsize) {
|
|
||||||
srcLen = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dest_size = LCMapStringEx(locale_, flags, src_, srcLen, NULL, 0,
|
|
||||||
NULL, NULL, 0);
|
|
||||||
if (dest_size == 0) {
|
|
||||||
PyMem_Free(locale_);
|
PyMem_Free(locale_);
|
||||||
PyMem_Free(src_);
|
PyMem_Free(src_);
|
||||||
return PyErr_SetFromWindowsErr(0);
|
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) {
|
||||||
|
DWORD error = GetLastError();
|
||||||
|
PyMem_Free(locale_);
|
||||||
|
PyMem_Free(src_);
|
||||||
|
return PyErr_SetFromWindowsErr(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t* dest = PyMem_NEW(wchar_t, dest_size);
|
wchar_t* dest = PyMem_NEW(wchar_t, dest_size);
|
||||||
|
@ -1598,9 +1600,9 @@ _winapi_LCMapStringEx_impl(PyObject *module, PyObject *locale, DWORD flags,
|
||||||
return PyErr_NoMemory();
|
return PyErr_NoMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
int nmapped = LCMapStringEx(locale_, flags, src_, srcLen, dest, dest_size,
|
int nmapped = LCMapStringEx(locale_, flags, src_, (int)src_size, dest, dest_size,
|
||||||
NULL, NULL, 0);
|
NULL, NULL, 0);
|
||||||
if (nmapped == 0) {
|
if (nmapped <= 0) {
|
||||||
DWORD error = GetLastError();
|
DWORD error = GetLastError();
|
||||||
PyMem_Free(locale_);
|
PyMem_Free(locale_);
|
||||||
PyMem_Free(src_);
|
PyMem_Free(src_);
|
||||||
|
@ -1608,9 +1610,9 @@ _winapi_LCMapStringEx_impl(PyObject *module, PyObject *locale, DWORD flags,
|
||||||
return PyErr_SetFromWindowsErr(error);
|
return PyErr_SetFromWindowsErr(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *ret = PyUnicode_FromWideChar(dest, dest_size);
|
|
||||||
PyMem_Free(locale_);
|
PyMem_Free(locale_);
|
||||||
PyMem_Free(src_);
|
PyMem_Free(src_);
|
||||||
|
PyObject *ret = PyUnicode_FromWideChar(dest, nmapped);
|
||||||
PyMem_DEL(dest);
|
PyMem_DEL(dest);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in New Issue