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 @@ class TestCurses(unittest.TestCase): 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 @@ class TestCurses(unittest.TestCase): 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