]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
#18113: Objects associated to a curses.panel object with set_userptr() were leaked.
authorAndrew Kuchling <amk@amk.ca>
Sat, 15 Jun 2013 17:53:10 +0000 (13:53 -0400)
committerAndrew Kuchling <amk@amk.ca>
Sat, 15 Jun 2013 17:53:10 +0000 (13:53 -0400)
Reported by Atsuo Ishimoto.

Lib/test/test_curses.py
Misc/NEWS
Modules/_curses_panel.c

index fa0d469e475f4459565c8a3591dae243840382e1..387a1852d9d1e1bccc33eba27fd67e0a07afc9c8 100644 (file)
@@ -250,6 +250,18 @@ def test_userptr_without_set(stdscr):
     except curses.panel.error:
         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):
     if hasattr(curses, 'resizeterm'):
         lines, cols = curses.LINES, curses.COLS
@@ -268,6 +280,7 @@ def main(stdscr):
         module_funcs(stdscr)
         window_funcs(stdscr)
         test_userptr_without_set(stdscr)
+        test_userptr_memory_leak(stdscr)
         test_resize_term(stdscr)
         test_issue6243(stdscr)
     finally:
index 1479f8497801e002b85ba53c3cb817f792ee7d0c..efcd20a3900e5d83f16835a148ec137a9eb9cb53 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -40,6 +40,9 @@ Library
   the default for linking if LDSHARED is not also overriden.  This restores
   Distutils behavior introduced in 2.7.3 and inadvertently dropped in 2.7.4.
 
+- Issue #18113: Fixed a refcount leak in the curses.panel module's
+  set_userptr() method.  Reported by Atsuo Ishimoto.
+
 Build
 -----
 
index 04a0a28a885f3e954a170a7b3523a2e30a2ca05a..dd231e767fa1bf0895d7fb47f265bc10b9758bd0 100644 (file)
@@ -293,6 +293,10 @@ PyCursesPanel_replace_panel(PyCursesPanelObject *self, PyObject *args)
 static PyObject *
 PyCursesPanel_set_panel_userptr(PyCursesPanelObject *self, PyObject *obj)
 {
+    PyObject *oldobj;
+    PyCursesInitialised;
+    oldobj = (PyObject *) panel_userptr(self->pan);
+    Py_XDECREF(oldobj);
     Py_INCREF(obj);
     return PyCursesCheckERR(set_panel_userptr(self->pan, (void*)obj),
                             "set_panel_userptr");