changeset: 104529:6b3be9f38f2a branch: 3.5 parent: 104524:14363cf42e15 user: Serhiy Storchaka date: Tue Oct 18 13:23:18 2016 +0300 files: Misc/NEWS Python/traceback.c description: Issue #23782: Fixed possible memory leak in _PyTraceback_Add() and exception loss in PyTraceBack_Here(). diff -r 14363cf42e15 -r 6b3be9f38f2a Misc/NEWS --- a/Misc/NEWS Tue Oct 18 00:34:46 2016 +0300 +++ b/Misc/NEWS Tue Oct 18 13:23:18 2016 +0300 @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #23782: Fixed possible memory leak in _PyTraceback_Add() and exception + loss in PyTraceBack_Here(). + - Issue #28379: Added sanity checks and tests for PyUnicode_CopyCharacters(). Patch by Xiang Zhang. diff -r 14363cf42e15 -r 6b3be9f38f2a Python/traceback.c --- a/Python/traceback.c Tue Oct 18 00:34:46 2016 +0300 +++ b/Python/traceback.c Tue Oct 18 13:23:18 2016 +0300 @@ -132,47 +132,53 @@ int PyTraceBack_Here(PyFrameObject *frame) { - PyThreadState *tstate = PyThreadState_GET(); - PyTracebackObject *oldtb = (PyTracebackObject *) tstate->curexc_traceback; - PyTracebackObject *tb = newtracebackobject(oldtb, frame); - if (tb == NULL) + PyObject *exc, *val, *tb, *newtb; + PyErr_Fetch(&exc, &val, &tb); + newtb = (PyObject *)newtracebackobject((PyTracebackObject *)tb, frame); + if (newtb == NULL) { + _PyErr_ChainExceptions(exc, val, tb); return -1; - tstate->curexc_traceback = (PyObject *)tb; - Py_XDECREF(oldtb); + } + PyErr_Restore(exc, val, newtb); + Py_XDECREF(tb); return 0; } /* Insert a frame into the traceback for (funcname, filename, lineno). */ void _PyTraceback_Add(const char *funcname, const char *filename, int lineno) { - PyObject *globals = NULL; - PyCodeObject *code = NULL; - PyFrameObject *frame = NULL; - PyObject *exception, *value, *tb; + PyObject *globals; + PyCodeObject *code; + PyFrameObject *frame; + PyObject *exc, *val, *tb; /* Save and clear the current exception. Python functions must not be called with an exception set. Calling Python functions happens when the codec of the filesystem encoding is implemented in pure Python. */ - PyErr_Fetch(&exception, &value, &tb); + PyErr_Fetch(&exc, &val, &tb); globals = PyDict_New(); if (!globals) - goto done; + goto error; code = PyCode_NewEmpty(filename, funcname, lineno); - if (!code) - goto done; + if (!code) { + Py_DECREF(globals); + goto error; + } frame = PyFrame_New(PyThreadState_Get(), code, globals, NULL); + Py_DECREF(globals); + Py_DECREF(code); if (!frame) - goto done; + goto error; frame->f_lineno = lineno; - PyErr_Restore(exception, value, tb); + PyErr_Restore(exc, val, tb); PyTraceBack_Here(frame); + Py_DECREF(frame); + return; -done: - Py_XDECREF(globals); - Py_XDECREF(code); - Py_XDECREF(frame); +error: + _PyErr_ChainExceptions(exc, val, tb); } static PyObject *