Commit aa6c2973 authored by Andrew Kuchling's avatar Andrew Kuchling

#18113: avoid segfault if Py_XDECREF triggers code that calls set_panel_userptr again

Problem noted & original patch by Serhiy Storchaka; I tweaked the patch a bit.
parent 22b4b4ce
...@@ -262,6 +262,14 @@ def test_userptr_memory_leak(stdscr): ...@@ -262,6 +262,14 @@ def test_userptr_memory_leak(stdscr):
if sys.getrefcount(obj) != nrefs: if sys.getrefcount(obj) != nrefs:
raise RuntimeError, "set_userptr leaked references" raise RuntimeError, "set_userptr leaked references"
def test_userptr_segfault(stdscr):
panel = curses.panel.new_panel(stdscr)
class A:
def __del__(self):
panel.set_userptr(None)
panel.set_userptr(A())
panel.set_userptr(None)
def test_resize_term(stdscr): def test_resize_term(stdscr):
if hasattr(curses, 'resizeterm'): if hasattr(curses, 'resizeterm'):
lines, cols = curses.LINES, curses.COLS lines, cols = curses.LINES, curses.COLS
...@@ -281,6 +289,7 @@ def main(stdscr): ...@@ -281,6 +289,7 @@ def main(stdscr):
window_funcs(stdscr) window_funcs(stdscr)
test_userptr_without_set(stdscr) test_userptr_without_set(stdscr)
test_userptr_memory_leak(stdscr) test_userptr_memory_leak(stdscr)
test_userptr_segfault(stdscr)
test_resize_term(stdscr) test_resize_term(stdscr)
test_issue6243(stdscr) test_issue6243(stdscr)
finally: finally:
......
...@@ -294,12 +294,17 @@ static PyObject * ...@@ -294,12 +294,17 @@ static PyObject *
PyCursesPanel_set_panel_userptr(PyCursesPanelObject *self, PyObject *obj) PyCursesPanel_set_panel_userptr(PyCursesPanelObject *self, PyObject *obj)
{ {
PyObject *oldobj; PyObject *oldobj;
int rc;
PyCursesInitialised; PyCursesInitialised;
Py_INCREF(obj);
oldobj = (PyObject *) panel_userptr(self->pan); oldobj = (PyObject *) panel_userptr(self->pan);
rc = set_panel_userptr(self->pan, (void*)obj);
if (rc == ERR) {
/* In case of an ncurses error, decref the new object again */
Py_DECREF(obj);
}
Py_XDECREF(oldobj); Py_XDECREF(oldobj);
Py_INCREF(obj); return PyCursesCheckERR(rc, "set_panel_userptr");
return PyCursesCheckERR(set_panel_userptr(self->pan, (void*)obj),
"set_panel_userptr");
} }
static PyObject * static PyObject *
......
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