[Python-checkins] bpo-27666: Fixed stack corruption in curses.box() and curses.ungetmouse(). (#4220)

Serhiy Storchaka webhook-mailer at python.org
Wed Nov 1 14:48:54 EDT 2017


https://github.com/python/cpython/commit/4f469c096628af730b17798d0ebfd8925bfde836
commit: 4f469c096628af730b17798d0ebfd8925bfde836
branch: master
author: Serhiy Storchaka <storchaka at gmail.com>
committer: GitHub <noreply at github.com>
date: 2017-11-01T20:48:49+02:00
summary:

bpo-27666: Fixed stack corruption in curses.box() and curses.ungetmouse(). (#4220)

files:
A Misc/NEWS.d/next/Library/2017-11-01-18-13-42.bpo-27666.j2zRnF.rst
M Lib/test/test_curses.py
M Modules/_cursesmodule.c

diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py
index 8bb6630284d..17b3af47c35 100644
--- a/Lib/test/test_curses.py
+++ b/Lib/test/test_curses.py
@@ -92,7 +92,7 @@ def test_window_funcs(self):
                 with self.subTest(meth=meth.__qualname__, args=args):
                     meth(*args)
 
-        for meth in [stdscr.box, stdscr.clear, stdscr.clrtobot,
+        for meth in [stdscr.clear, stdscr.clrtobot,
                      stdscr.clrtoeol, stdscr.cursyncup, stdscr.delch,
                      stdscr.deleteln, stdscr.erase, stdscr.getbegyx,
                      stdscr.getbkgd, stdscr.getkey, stdscr.getmaxyx,
@@ -126,6 +126,13 @@ def test_window_funcs(self):
             win.border(65, 66, 67, 68,
                        69, [], 71, 72)
 
+        win.box(65, 67)
+        win.box('!', '_')
+        win.box(b':', b'~')
+        self.assertRaises(TypeError, win.box, 65, 66, 67)
+        self.assertRaises(TypeError, win.box, 65)
+        win.box()
+
         stdscr.clearok(1)
 
         win4 = stdscr.derwin(2,2)
diff --git a/Misc/NEWS.d/next/Library/2017-11-01-18-13-42.bpo-27666.j2zRnF.rst b/Misc/NEWS.d/next/Library/2017-11-01-18-13-42.bpo-27666.j2zRnF.rst
new file mode 100644
index 00000000000..a74f0adfa16
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2017-11-01-18-13-42.bpo-27666.j2zRnF.rst
@@ -0,0 +1,3 @@
+Fixed stack corruption in curses.box() and curses.ungetmouse() when the size
+of types chtype or mmask_t is less than the size of C long.  curses.box()
+now accepts characters as arguments.  Based on patch by Steve Fink.
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c
index 1f6897a5701..ae1905b8a90 100644
--- a/Modules/_cursesmodule.c
+++ b/Modules/_cursesmodule.c
@@ -911,12 +911,19 @@ PyCursesWindow_Border(PyCursesWindowObject *self, PyObject *args)
 static PyObject *
 PyCursesWindow_Box(PyCursesWindowObject *self, PyObject *args)
 {
+    PyObject *temp1, *temp2;
     chtype ch1=0,ch2=0;
     switch(PyTuple_Size(args)){
     case 0: break;
     default:
-        if (!PyArg_ParseTuple(args,"ll;vertint,horint", &ch1, &ch2))
+        if (!PyArg_ParseTuple(args,"OO;verch,horch", &temp1, &temp2))
             return NULL;
+        if (!PyCurses_ConvertToChtype(self, temp1, &ch1)) {
+            return NULL;
+        }
+        if (!PyCurses_ConvertToChtype(self, temp2, &ch2)) {
+            return NULL;
+        }
     }
     box(self->win,ch1,ch2);
     Py_RETURN_NONE;
@@ -2268,24 +2275,30 @@ PyCurses_GetMouse(PyObject *self)
         PyErr_SetString(PyCursesError, "getmouse() returned ERR");
         return NULL;
     }
-    return Py_BuildValue("(hiiil)",
+    return Py_BuildValue("(hiiik)",
                          (short)event.id,
-                         event.x, event.y, event.z,
-                         (long) event.bstate);
+                         (int)event.x, (int)event.y, (int)event.z,
+                         (unsigned long) event.bstate);
 }
 
 static PyObject *
 PyCurses_UngetMouse(PyObject *self, PyObject *args)
 {
     MEVENT event;
+    short id;
+    int x, y, z;
+    unsigned long bstate;
 
     PyCursesInitialised;
-    if (!PyArg_ParseTuple(args, "hiiil",
-                          &event.id,
-                          &event.x, &event.y, &event.z,
-                          (int *) &event.bstate))
+    if (!PyArg_ParseTuple(args, "hiiik",
+                          &id, &x, &y, &z, &bstate))
         return NULL;
 
+    event.id = id;
+    event.x = x;
+    event.y = y;
+    event.z = z;
+    event.bstate = bstate;
     return PyCursesCheckERR(ungetmouse(&event), "ungetmouse");
 }
 #endif
@@ -2669,14 +2682,15 @@ PyCurses_MouseInterval(PyObject *self, PyObject *args)
 static PyObject *
 PyCurses_MouseMask(PyObject *self, PyObject *args)
 {
-    int newmask;
+    unsigned long newmask;
     mmask_t oldmask, availmask;
 
     PyCursesInitialised;
-    if (!PyArg_ParseTuple(args,"i;mousemask",&newmask))
+    if (!PyArg_ParseTuple(args,"k;mousemask",&newmask))
         return NULL;
-    availmask = mousemask(newmask, &oldmask);
-    return Py_BuildValue("(ll)", (long)availmask, (long)oldmask);
+    availmask = mousemask((mmask_t)newmask, &oldmask);
+    return Py_BuildValue("(kk)",
+                         (unsigned long)availmask, (unsigned long)oldmask);
 }
 #endif
 



More information about the Python-checkins mailing list