@@ -2282,46 +2282,70 @@ static PyObject *
22822282OSError_str (PyObject * op )
22832283{
22842284 PyOSErrorObject * self = PyOSErrorObject_CAST (op );
2285+ PyObject * res ;
2286+ /* Hold strong references: formatting may run arbitrary code
2287+ which modifies the attributes. */
2288+ PyObject * myerrno = Py_XNewRef (self -> myerrno );
2289+ PyObject * strerror = Py_XNewRef (self -> strerror );
2290+ PyObject * filename = Py_XNewRef (self -> filename );
2291+ PyObject * filename2 = Py_XNewRef (self -> filename2 );
2292+ #ifdef MS_WINDOWS
2293+ PyObject * winerror = Py_XNewRef (self -> winerror );
2294+ #endif
22852295#define OR_NONE (x ) ((x)?(x):Py_None)
22862296#ifdef MS_WINDOWS
22872297 /* If available, winerror has the priority over myerrno */
2288- if (self -> winerror && self -> filename ) {
2289- if (self -> filename2 ) {
2290- return PyUnicode_FromFormat ("[WinError %S] %S: %R -> %R" ,
2291- OR_NONE (self -> winerror ),
2292- OR_NONE (self -> strerror ),
2293- self -> filename ,
2294- self -> filename2 );
2298+ if (winerror && filename ) {
2299+ if (filename2 ) {
2300+ res = PyUnicode_FromFormat ("[WinError %S] %S: %R -> %R" ,
2301+ OR_NONE (winerror ),
2302+ OR_NONE (strerror ),
2303+ filename ,
2304+ filename2 );
22952305 } else {
2296- return PyUnicode_FromFormat ("[WinError %S] %S: %R" ,
2297- OR_NONE (self -> winerror ),
2298- OR_NONE (self -> strerror ),
2299- self -> filename );
2306+ res = PyUnicode_FromFormat ("[WinError %S] %S: %R" ,
2307+ OR_NONE (winerror ),
2308+ OR_NONE (strerror ),
2309+ filename );
23002310 }
2311+ goto done ;
2312+ }
2313+ if (winerror && strerror ) {
2314+ res = PyUnicode_FromFormat ("[WinError %S] %S" ,
2315+ winerror , strerror );
2316+ goto done ;
23012317 }
2302- if (self -> winerror && self -> strerror )
2303- return PyUnicode_FromFormat ("[WinError %S] %S" ,
2304- self -> winerror ? self -> winerror : Py_None ,
2305- self -> strerror ? self -> strerror : Py_None );
23062318#endif
2307- if (self -> filename ) {
2308- if (self -> filename2 ) {
2309- return PyUnicode_FromFormat ("[Errno %S] %S: %R -> %R" ,
2310- OR_NONE (self -> myerrno ),
2311- OR_NONE (self -> strerror ),
2312- self -> filename ,
2313- self -> filename2 );
2319+ if (filename ) {
2320+ if (filename2 ) {
2321+ res = PyUnicode_FromFormat ("[Errno %S] %S: %R -> %R" ,
2322+ OR_NONE (myerrno ),
2323+ OR_NONE (strerror ),
2324+ filename ,
2325+ filename2 );
23142326 } else {
2315- return PyUnicode_FromFormat ("[Errno %S] %S: %R" ,
2316- OR_NONE (self -> myerrno ),
2317- OR_NONE (self -> strerror ),
2318- self -> filename );
2327+ res = PyUnicode_FromFormat ("[Errno %S] %S: %R" ,
2328+ OR_NONE (myerrno ),
2329+ OR_NONE (strerror ),
2330+ filename );
23192331 }
2332+ goto done ;
23202333 }
2321- if (self -> myerrno && self -> strerror )
2322- return PyUnicode_FromFormat ("[Errno %S] %S" ,
2323- self -> myerrno , self -> strerror );
2324- return BaseException_str (op );
2334+ if (myerrno && strerror ) {
2335+ res = PyUnicode_FromFormat ("[Errno %S] %S" ,
2336+ myerrno , strerror );
2337+ goto done ;
2338+ }
2339+ res = BaseException_str (op );
2340+ done :
2341+ Py_XDECREF (myerrno );
2342+ Py_XDECREF (strerror );
2343+ Py_XDECREF (filename );
2344+ Py_XDECREF (filename2 );
2345+ #ifdef MS_WINDOWS
2346+ Py_XDECREF (winerror );
2347+ #endif
2348+ return res ;
23252349}
23262350
23272351static PyObject *
0 commit comments