Kaydet (Commit) 71fb5134 authored tarafından Thomas Heller's avatar Thomas Heller

Prevent UnicodeDecodeErrors in ctypes with non-ascii error messages.

Fixes issue #4429.

Reviewed by Amaury Forgeot d'Arc.
üst d951e7b3
...@@ -22,6 +22,8 @@ Core and Builtins ...@@ -22,6 +22,8 @@ Core and Builtins
Library Library
------- -------
- Issue #4429: Fixed UnicodeDecodeError in ctypes.
- Issue #4373: Corrected a potential reference leak in the pickle module and - Issue #4373: Corrected a potential reference leak in the pickle module and
silenced a false positive ref leak in distutils.tests.test_build_ext. silenced a false positive ref leak in distutils.tests.test_build_ext.
......
...@@ -209,21 +209,21 @@ set_last_error(PyObject *self, PyObject *args) ...@@ -209,21 +209,21 @@ set_last_error(PyObject *self, PyObject *args)
PyObject *ComError; PyObject *ComError;
static TCHAR *FormatError(DWORD code) static WCHAR *FormatError(DWORD code)
{ {
TCHAR *lpMsgBuf; WCHAR *lpMsgBuf;
DWORD n; DWORD n;
n = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, n = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, NULL,
code, code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf, (LPWSTR) &lpMsgBuf,
0, 0,
NULL); NULL);
if (n) { if (n) {
while (_istspace(lpMsgBuf[n-1])) while (iswspace(lpMsgBuf[n-1]))
--n; --n;
lpMsgBuf[n] = _T('\0'); /* rstrip() */ lpMsgBuf[n] = L'\0'; /* rstrip() */
} }
return lpMsgBuf; return lpMsgBuf;
} }
...@@ -231,7 +231,7 @@ static TCHAR *FormatError(DWORD code) ...@@ -231,7 +231,7 @@ static TCHAR *FormatError(DWORD code)
#ifndef DONT_USE_SEH #ifndef DONT_USE_SEH
void SetException(DWORD code, EXCEPTION_RECORD *pr) void SetException(DWORD code, EXCEPTION_RECORD *pr)
{ {
TCHAR *lpMsgBuf; WCHAR *lpMsgBuf;
lpMsgBuf = FormatError(code); lpMsgBuf = FormatError(code);
if(lpMsgBuf) { if(lpMsgBuf) {
PyErr_SetFromWindowsErr(code); PyErr_SetFromWindowsErr(code);
...@@ -972,7 +972,7 @@ GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk) ...@@ -972,7 +972,7 @@ GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk)
DWORD helpcontext=0; DWORD helpcontext=0;
LPOLESTR progid; LPOLESTR progid;
PyObject *obj; PyObject *obj;
TCHAR *text; LPOLESTR text;
/* We absolutely have to release the GIL during COM method calls, /* We absolutely have to release the GIL during COM method calls,
otherwise we may get a deadlock! otherwise we may get a deadlock!
...@@ -1012,11 +1012,7 @@ GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk) ...@@ -1012,11 +1012,7 @@ GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk)
text = FormatError(errcode); text = FormatError(errcode);
obj = Py_BuildValue( obj = Py_BuildValue(
#ifdef _UNICODE
"iu(uuuiu)", "iu(uuuiu)",
#else
"is(uuuiu)",
#endif
errcode, errcode,
text, text,
descr, source, helpfile, helpcontext, descr, source, helpfile, helpcontext,
...@@ -1202,15 +1198,6 @@ _parse_voidp(PyObject *obj, void **address) ...@@ -1202,15 +1198,6 @@ _parse_voidp(PyObject *obj, void **address)
#ifdef MS_WIN32 #ifdef MS_WIN32
#ifdef _UNICODE
# define PYBUILD_TSTR "u"
#else
# define PYBUILD_TSTR "s"
# ifndef _T
# define _T(text) text
# endif
#endif
static char format_error_doc[] = static char format_error_doc[] =
"FormatError([integer]) -> string\n\ "FormatError([integer]) -> string\n\
\n\ \n\
...@@ -1219,7 +1206,7 @@ given, the return value of a call to GetLastError() is used.\n"; ...@@ -1219,7 +1206,7 @@ given, the return value of a call to GetLastError() is used.\n";
static PyObject *format_error(PyObject *self, PyObject *args) static PyObject *format_error(PyObject *self, PyObject *args)
{ {
PyObject *result; PyObject *result;
TCHAR *lpMsgBuf; wchar_t *lpMsgBuf;
DWORD code = 0; DWORD code = 0;
if (!PyArg_ParseTuple(args, "|i:FormatError", &code)) if (!PyArg_ParseTuple(args, "|i:FormatError", &code))
return NULL; return NULL;
...@@ -1227,10 +1214,10 @@ static PyObject *format_error(PyObject *self, PyObject *args) ...@@ -1227,10 +1214,10 @@ static PyObject *format_error(PyObject *self, PyObject *args)
code = GetLastError(); code = GetLastError();
lpMsgBuf = FormatError(code); lpMsgBuf = FormatError(code);
if (lpMsgBuf) { if (lpMsgBuf) {
result = Py_BuildValue(PYBUILD_TSTR, lpMsgBuf); result = PyUnicode_FromWideChar(lpMsgBuf, wcslen(lpMsgBuf));
LocalFree(lpMsgBuf); LocalFree(lpMsgBuf);
} else { } else {
result = Py_BuildValue("s", "<no description>"); result = PyUnicode_FromString("<no description>");
} }
return result; return result;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment