Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Lib/test/test_ntpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -1036,6 +1036,7 @@ def test_path_normcase(self):
self._check_function(self.path.normcase)
if sys.platform == 'win32':
self.assertEqual(ntpath.normcase('\u03a9\u2126'), 'ωΩ')
self.assertEqual(ntpath.normcase('abc\x00def'), 'abc\x00def')

def test_path_isabs(self):
self._check_function(self.path.isabs)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix null-bytes handling in ``LCMapStringEx`` which affects
:func:`ntpath.normcase`.
27 changes: 21 additions & 6 deletions Modules/_winapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1539,40 +1539,55 @@ _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) {
PyMem_Free(src_);
return PyErr_SetFromWindowsErr(0);
}

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) {
DWORD error = GetLastError();
PyMem_Free(src_);
PyMem_DEL(dest);
return PyErr_SetFromWindowsErr(error);
}

PyObject *ret = PyUnicode_FromWideChar(dest, dest_size - 1);
PyObject *ret = PyUnicode_FromWideChar(dest, dest_size);
PyMem_Free(src_);
PyMem_DEL(dest);

return ret;
Expand Down
12 changes: 5 additions & 7 deletions Modules/clinic/_winapi.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.