[Python-checkins] cpython (2.7): #18113: avoid segfault if Py_XDECREF triggers code that calls set_panel_userptr

andrew.kuchling python-checkins at python.org
Sat Jun 22 18:33:21 CEST 2013


http://hg.python.org/cpython/rev/99733ff98a50
changeset:   84251:99733ff98a50
branch:      2.7
parent:      84248:f1dc30a1be72
user:        Andrew Kuchling <amk at amk.ca>
date:        Sat Jun 22 12:33:05 2013 -0400
summary:
  #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.

files:
  Lib/test/test_curses.py |   9 +++++++++
  Modules/_curses_panel.c |  11 ++++++++---
  2 files changed, 17 insertions(+), 3 deletions(-)


diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py
--- a/Lib/test/test_curses.py
+++ b/Lib/test/test_curses.py
@@ -262,6 +262,14 @@
     if sys.getrefcount(obj) != nrefs:
         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):
     if hasattr(curses, 'resizeterm'):
         lines, cols = curses.LINES, curses.COLS
@@ -281,6 +289,7 @@
         window_funcs(stdscr)
         test_userptr_without_set(stdscr)
         test_userptr_memory_leak(stdscr)
+        test_userptr_segfault(stdscr)
         test_resize_term(stdscr)
         test_issue6243(stdscr)
     finally:
diff --git a/Modules/_curses_panel.c b/Modules/_curses_panel.c
--- a/Modules/_curses_panel.c
+++ b/Modules/_curses_panel.c
@@ -294,12 +294,17 @@
 PyCursesPanel_set_panel_userptr(PyCursesPanelObject *self, PyObject *obj)
 {
     PyObject *oldobj;
+    int rc;
     PyCursesInitialised;
+    Py_INCREF(obj);
     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_INCREF(obj);
-    return PyCursesCheckERR(set_panel_userptr(self->pan, (void*)obj),
-                            "set_panel_userptr");
+    return PyCursesCheckERR(rc, "set_panel_userptr");
 }
 
 static PyObject *

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list