Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 71fb513

Browse files
author
Thomas Heller
committed
Prevent UnicodeDecodeErrors in ctypes with non-ascii error messages.
Fixes issue #4429. Reviewed by Amaury Forgeot d'Arc.
1 parent d951e7b commit 71fb513

2 files changed

Lines changed: 18 additions & 29 deletions

File tree

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ Core and Builtins
2222
Library
2323
-------
2424

25+
- Issue #4429: Fixed UnicodeDecodeError in ctypes.
26+
2527
- Issue #4373: Corrected a potential reference leak in the pickle module and
2628
silenced a false positive ref leak in distutils.tests.test_build_ext.
2729

Modules/_ctypes/callproc.c

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -209,29 +209,29 @@ set_last_error(PyObject *self, PyObject *args)
209209

210210
PyObject *ComError;
211211

212-
static TCHAR *FormatError(DWORD code)
212+
static WCHAR *FormatError(DWORD code)
213213
{
214-
TCHAR *lpMsgBuf;
214+
WCHAR *lpMsgBuf;
215215
DWORD n;
216-
n = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
217-
NULL,
218-
code,
219-
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
220-
(LPTSTR) &lpMsgBuf,
221-
0,
222-
NULL);
216+
n = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
217+
NULL,
218+
code,
219+
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
220+
(LPWSTR) &lpMsgBuf,
221+
0,
222+
NULL);
223223
if (n) {
224-
while (_istspace(lpMsgBuf[n-1]))
224+
while (iswspace(lpMsgBuf[n-1]))
225225
--n;
226-
lpMsgBuf[n] = _T('\0'); /* rstrip() */
226+
lpMsgBuf[n] = L'\0'; /* rstrip() */
227227
}
228228
return lpMsgBuf;
229229
}
230230

231231
#ifndef DONT_USE_SEH
232232
void SetException(DWORD code, EXCEPTION_RECORD *pr)
233233
{
234-
TCHAR *lpMsgBuf;
234+
WCHAR *lpMsgBuf;
235235
lpMsgBuf = FormatError(code);
236236
if(lpMsgBuf) {
237237
PyErr_SetFromWindowsErr(code);
@@ -972,7 +972,7 @@ GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk)
972972
DWORD helpcontext=0;
973973
LPOLESTR progid;
974974
PyObject *obj;
975-
TCHAR *text;
975+
LPOLESTR text;
976976

977977
/* We absolutely have to release the GIL during COM method calls,
978978
otherwise we may get a deadlock!
@@ -1012,11 +1012,7 @@ GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk)
10121012

10131013
text = FormatError(errcode);
10141014
obj = Py_BuildValue(
1015-
#ifdef _UNICODE
10161015
"iu(uuuiu)",
1017-
#else
1018-
"is(uuuiu)",
1019-
#endif
10201016
errcode,
10211017
text,
10221018
descr, source, helpfile, helpcontext,
@@ -1202,15 +1198,6 @@ _parse_voidp(PyObject *obj, void **address)
12021198

12031199
#ifdef MS_WIN32
12041200

1205-
#ifdef _UNICODE
1206-
# define PYBUILD_TSTR "u"
1207-
#else
1208-
# define PYBUILD_TSTR "s"
1209-
# ifndef _T
1210-
# define _T(text) text
1211-
# endif
1212-
#endif
1213-
12141201
static char format_error_doc[] =
12151202
"FormatError([integer]) -> string\n\
12161203
\n\
@@ -1219,18 +1206,18 @@ given, the return value of a call to GetLastError() is used.\n";
12191206
static PyObject *format_error(PyObject *self, PyObject *args)
12201207
{
12211208
PyObject *result;
1222-
TCHAR *lpMsgBuf;
1209+
wchar_t *lpMsgBuf;
12231210
DWORD code = 0;
12241211
if (!PyArg_ParseTuple(args, "|i:FormatError", &code))
12251212
return NULL;
12261213
if (code == 0)
12271214
code = GetLastError();
12281215
lpMsgBuf = FormatError(code);
12291216
if (lpMsgBuf) {
1230-
result = Py_BuildValue(PYBUILD_TSTR, lpMsgBuf);
1217+
result = PyUnicode_FromWideChar(lpMsgBuf, wcslen(lpMsgBuf));
12311218
LocalFree(lpMsgBuf);
12321219
} else {
1233-
result = Py_BuildValue("s", "<no description>");
1220+
result = PyUnicode_FromString("<no description>");
12341221
}
12351222
return result;
12361223
}

0 commit comments

Comments
 (0)