@@ -10,8 +10,8 @@ extern char *strerror(int);
1010#endif
1111
1212#ifdef MS_WINDOWS
13- #include " windows.h"
14- #include " winbase.h"
13+ #include < windows.h>
14+ #include < winbase.h>
1515#endif
1616
1717#include <ctype.h>
@@ -270,41 +270,49 @@ PyErr_NoMemory(void)
270270PyObject *
271271PyErr_SetFromErrnoWithFilenameObject (PyObject * exc , PyObject * filenameObject )
272272{
273+ PyObject * message ;
273274 PyObject * v ;
274- char * s ;
275275 int i = errno ;
276276#ifdef PLAN9
277277 char errbuf [ERRMAX ];
278- #endif
279- #ifdef MS_WINDOWS
280- char * s_buf = NULL ;
281- char s_small_buf [28 ]; /* Room for "Windows Error 0xFFFFFFFF" */
282- #endif
278+ #else
279+ #ifndef MS_WINDOWS
280+ char * s ;
281+ #else
282+ WCHAR * s_buf = NULL ;
283+ #endif /* Unix/Windows */
284+ #endif /* PLAN 9*/
285+
283286#ifdef EINTR
284287 if (i == EINTR && PyErr_CheckSignals ())
285288 return NULL ;
286289#endif
290+
287291#ifdef PLAN9
288292 rerrstr (errbuf , sizeof errbuf );
289- s = errbuf ;
293+ message = PyUnicode_DecodeUTF8 ( errbuf , strlen ( errbuf ), "ignore" ) ;
290294#else
295+ #ifndef MS_WINDOWS
291296 if (i == 0 )
292297 s = "Error" ; /* Sometimes errno didn't get set */
293298 else
294- #ifndef MS_WINDOWS
295299 s = strerror (i );
300+ message = PyUnicode_DecodeUTF8 (s , strlen (s ), "ignore" );
296301#else
302+ if (i == 0 )
303+ message = PyUnicode_FromString ("Error" ); /* Sometimes errno didn't get set */
304+ else
297305 {
298306 /* Note that the Win32 errors do not lineup with the
299307 errno error. So if the error is in the MSVC error
300308 table, we use it, otherwise we assume it really _is_
301309 a Win32 error code
302310 */
303311 if (i > 0 && i < _sys_nerr ) {
304- s = _sys_errlist [i ];
312+ message = PyUnicode_FromString ( _sys_errlist [i ]) ;
305313 }
306314 else {
307- int len = FormatMessage (
315+ int len = FormatMessageW (
308316 FORMAT_MESSAGE_ALLOCATE_BUFFER |
309317 FORMAT_MESSAGE_FROM_SYSTEM |
310318 FORMAT_MESSAGE_IGNORE_INSERTS ,
@@ -313,29 +321,39 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
313321 MAKELANGID (LANG_NEUTRAL ,
314322 SUBLANG_DEFAULT ),
315323 /* Default language */
316- (LPTSTR ) & s_buf ,
324+ (LPWSTR ) & s_buf ,
317325 0 , /* size not used */
318326 NULL ); /* no args */
319327 if (len == 0 ) {
320328 /* Only ever seen this in out-of-mem
321329 situations */
322- sprintf (s_small_buf , "Windows Error 0x%X" , i );
323- s = s_small_buf ;
324330 s_buf = NULL ;
331+ message = PyUnicode_FromFormat ("Windows Error 0x%X" , i );
325332 } else {
326- s = s_buf ;
327333 /* remove trailing cr/lf and dots */
328- while (len > 0 && (s [len - 1 ] <= ' ' || s [len - 1 ] == '.' ))
329- s [-- len ] = '\0' ;
334+ while (len > 0 && (s_buf [len - 1 ] <= L' ' || s_buf [len - 1 ] == L'.' ))
335+ s_buf [-- len ] = L'\0' ;
336+ message = PyUnicode_FromUnicode (s_buf , len );
330337 }
331338 }
332339 }
333340#endif /* Unix/Windows */
334341#endif /* PLAN 9*/
342+
343+ if (message == NULL )
344+ {
345+ #ifdef MS_WINDOWS
346+ LocalFree (s_buf );
347+ #endif
348+ return NULL ;
349+ }
350+
335351 if (filenameObject != NULL )
336- v = Py_BuildValue ("(iUO )" , i , s , filenameObject );
352+ v = Py_BuildValue ("(iOO )" , i , message , filenameObject );
337353 else
338- v = Py_BuildValue ("(iU)" , i , s );
354+ v = Py_BuildValue ("(iO)" , i , message );
355+ Py_DECREF (message );
356+
339357 if (v != NULL ) {
340358 PyErr_SetObject (exc , v );
341359 Py_DECREF (v );
@@ -383,13 +401,12 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(
383401 PyObject * filenameObject )
384402{
385403 int len ;
386- char * s ;
387- char * s_buf = NULL ; /* Free via LocalFree */
388- char s_small_buf [28 ]; /* Room for "Windows Error 0xFFFFFFFF" */
404+ WCHAR * s_buf = NULL ; /* Free via LocalFree */
405+ PyObject * message ;
389406 PyObject * v ;
390407 DWORD err = (DWORD )ierr ;
391408 if (err == 0 ) err = GetLastError ();
392- len = FormatMessage (
409+ len = FormatMessageW (
393410 /* Error API error */
394411 FORMAT_MESSAGE_ALLOCATE_BUFFER |
395412 FORMAT_MESSAGE_FROM_SYSTEM |
@@ -398,24 +415,32 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(
398415 err ,
399416 MAKELANGID (LANG_NEUTRAL ,
400417 SUBLANG_DEFAULT ), /* Default language */
401- (LPTSTR ) & s_buf ,
418+ (LPWSTR ) & s_buf ,
402419 0 , /* size not used */
403420 NULL ); /* no args */
404421 if (len == 0 ) {
405422 /* Only seen this in out of mem situations */
406- sprintf (s_small_buf , "Windows Error 0x%X" , err );
407- s = s_small_buf ;
423+ message = PyUnicode_FromFormat ("Windows Error 0x%X" , err );
408424 s_buf = NULL ;
409425 } else {
410- s = s_buf ;
411426 /* remove trailing cr/lf and dots */
412- while (len > 0 && (s [len - 1 ] <= ' ' || s [len - 1 ] == '.' ))
413- s [-- len ] = '\0' ;
427+ while (len > 0 && (s_buf [len - 1 ] <= L' ' || s_buf [len - 1 ] == L'.' ))
428+ s_buf [-- len ] = L'\0' ;
429+ message = PyUnicode_FromUnicode (s_buf , len );
414430 }
431+
432+ if (message == NULL )
433+ {
434+ LocalFree (s_buf );
435+ return NULL ;
436+ }
437+
415438 if (filenameObject != NULL )
416- v = Py_BuildValue ("(iUO )" , err , s , filenameObject );
439+ v = Py_BuildValue ("(iOO )" , err , message , filenameObject );
417440 else
418- v = Py_BuildValue ("(iU)" , err , s );
441+ v = Py_BuildValue ("(iO)" , err , message );
442+ Py_DECREF (message );
443+
419444 if (v != NULL ) {
420445 PyErr_SetObject (exc , v );
421446 Py_DECREF (v );
0 commit comments