Index: Python/errors.c =================================================================== --- Python/errors.c (revision 57856) +++ Python/errors.c (working copy) @@ -10,8 +10,8 @@ #endif #ifdef MS_WINDOWS -#include "windows.h" -#include "winbase.h" +#include +#include #endif #include @@ -270,30 +270,38 @@ PyObject * PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject) { + PyObject *message; PyObject *v; - char *s; int i = errno; #ifdef PLAN9 char errbuf[ERRMAX]; -#endif -#ifdef MS_WINDOWS - char *s_buf = NULL; - char s_small_buf[28]; /* Room for "Windows Error 0xFFFFFFFF" */ -#endif +#else +#ifndef MS_WINDOWS + char *s; +#else + WCHAR *s_buf = NULL; +#endif /* Unix/Windows */ +#endif /* PLAN 9*/ + #ifdef EINTR if (i == EINTR && PyErr_CheckSignals()) return NULL; #endif + #ifdef PLAN9 rerrstr(errbuf, sizeof errbuf); - s = errbuf; + message = PyUnicode_DecodeUTF8(errbuf, strlen(errbuf), "ignore"); #else +#ifndef MS_WINDOWS if (i == 0) s = "Error"; /* Sometimes errno didn't get set */ else -#ifndef MS_WINDOWS s = strerror(i); + message = PyUnicode_DecodeUTF8(s, strlen(s), "ignore"); #else + if (i == 0) + message = PyUnicode_FromString("Error"); /* Sometimes errno didn't get set */ + else { /* Note that the Win32 errors do not lineup with the errno error. So if the error is in the MSVC error @@ -301,10 +309,10 @@ a Win32 error code */ if (i > 0 && i < _sys_nerr) { - s = _sys_errlist[i]; + message = PyUnicode_FromString(_sys_errlist[i]); } else { - int len = FormatMessage( + int len = FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, @@ -313,29 +321,39 @@ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ - (LPTSTR) &s_buf, + (LPWSTR) &s_buf, 0, /* size not used */ NULL); /* no args */ if (len==0) { /* Only ever seen this in out-of-mem situations */ - sprintf(s_small_buf, "Windows Error 0x%X", i); - s = s_small_buf; s_buf = NULL; + message = PyUnicode_FromFormat("Windows Error 0x%X", i); } else { - s = s_buf; /* remove trailing cr/lf and dots */ - while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.')) - s[--len] = '\0'; + while (len > 0 && (s_buf[len-1] <= ' ' || s_buf[len-1] == '.')) + s_buf[--len] = '\0'; + message = PyUnicode_FromUnicode(s_buf, len); } } } #endif /* Unix/Windows */ #endif /* PLAN 9*/ + + if (message == NULL) + { +#ifdef MS_WINDOWS + LocalFree(s_buf); +#endif + return NULL; + } + if (filenameObject != NULL) - v = Py_BuildValue("(iUO)", i, s, filenameObject); + v = Py_BuildValue("(iOO)", i, message, filenameObject); else - v = Py_BuildValue("(iU)", i, s); + v = Py_BuildValue("(iO)", i, message); + Py_DECREF(message); + if (v != NULL) { PyErr_SetObject(exc, v); Py_DECREF(v); @@ -383,13 +401,12 @@ PyObject *filenameObject) { int len; - char *s; - char *s_buf = NULL; /* Free via LocalFree */ - char s_small_buf[28]; /* Room for "Windows Error 0xFFFFFFFF" */ + WCHAR *s_buf = NULL; /* Free via LocalFree */ + PyObject *message; PyObject *v; DWORD err = (DWORD)ierr; if (err==0) err = GetLastError(); - len = FormatMessage( + len = FormatMessageW( /* Error API error */ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | @@ -398,24 +415,32 @@ err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ - (LPTSTR) &s_buf, + (LPWSTR) &s_buf, 0, /* size not used */ NULL); /* no args */ if (len==0) { /* Only seen this in out of mem situations */ - sprintf(s_small_buf, "Windows Error 0x%X", err); - s = s_small_buf; + message = PyUnicode_FromFormat("Windows Error 0x%X", err); s_buf = NULL; } else { - s = s_buf; /* remove trailing cr/lf and dots */ - while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.')) - s[--len] = '\0'; + while (len > 0 && (s_buf[len-1] <= ' ' || s_buf[len-1] == '.')) + s_buf[--len] = '\0'; + message = PyUnicode_FromUnicode(s_buf, len); } + + if (message == NULL) + { + LocalFree(s_buf); + return NULL; + } + if (filenameObject != NULL) - v = Py_BuildValue("(iUO)", err, s, filenameObject); + v = Py_BuildValue("(iOO)", err, message, filenameObject); else - v = Py_BuildValue("(iU)", err, s); + v = Py_BuildValue("(iO)", err, message); + Py_DECREF(message); + if (v != NULL) { PyErr_SetObject(exc, v); Py_DECREF(v);