#18113: Objects associated to a curses.panel object with set_userptr() were leaked.

Reported by Atsuo Ishimoto.
This commit is contained in:
Andrew Kuchling 2013-06-15 14:04:04 -04:00
parent 27bbfdbc4c
commit 53e5ea7951
3 changed files with 20 additions and 0 deletions

View File

@ -252,6 +252,18 @@ def test_userptr_without_set(stdscr):
except curses.panel.error: except curses.panel.error:
pass pass
def test_userptr_memory_leak(stdscr):
w = curses.newwin(10, 10)
p = curses.panel.new_panel(w)
obj = object()
nrefs = sys.getrefcount(obj)
for i in range(100):
p.set_userptr(obj)
p.set_userptr(None)
if sys.getrefcount(obj) != nrefs:
raise RuntimeError("set_userptr leaked references")
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
@ -317,6 +329,7 @@ def main(stdscr):
module_funcs(stdscr) module_funcs(stdscr)
window_funcs(stdscr) window_funcs(stdscr)
test_userptr_without_set(stdscr) test_userptr_without_set(stdscr)
test_userptr_memory_leak(stdscr)
test_resize_term(stdscr) test_resize_term(stdscr)
test_issue6243(stdscr) test_issue6243(stdscr)
test_unget_wch(stdscr) test_unget_wch(stdscr)

View File

@ -78,6 +78,9 @@ Library
the default for linking if LDSHARED is not also overriden. This restores the default for linking if LDSHARED is not also overriden. This restores
Distutils behavior introduced in 3.2.3 and inadvertently dropped in 3.3.0. Distutils behavior introduced in 3.2.3 and inadvertently dropped in 3.3.0.
- Issue #18113: Fixed a refcount leak in the curses.panel module's
set_userptr() method. Reported by Atsuo Ishimoto.
IDLE IDLE
---- ----

View File

@ -322,6 +322,10 @@ PyCursesPanel_replace_panel(PyCursesPanelObject *self, PyObject *args)
static PyObject * static PyObject *
PyCursesPanel_set_panel_userptr(PyCursesPanelObject *self, PyObject *obj) PyCursesPanel_set_panel_userptr(PyCursesPanelObject *self, PyObject *obj)
{ {
PyObject *oldobj;
PyCursesInitialised;
oldobj = (PyObject *) panel_userptr(self->pan);
Py_XDECREF(oldobj);
Py_INCREF(obj); Py_INCREF(obj);
return PyCursesCheckERR(set_panel_userptr(self->pan, (void*)obj), return PyCursesCheckERR(set_panel_userptr(self->pan, (void*)obj),
"set_panel_userptr"); "set_panel_userptr");