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

This commit is contained in:
Serhiy Storchaka 2017-11-01 20:48:49 +02:00 committed by GitHub
parent 7e68790f3d
commit 4f469c0966
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 13 deletions

View File

@ -92,7 +92,7 @@ class TestCurses(unittest.TestCase):
with self.subTest(meth=meth.__qualname__, args=args): with self.subTest(meth=meth.__qualname__, args=args):
meth(*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.clrtoeol, stdscr.cursyncup, stdscr.delch,
stdscr.deleteln, stdscr.erase, stdscr.getbegyx, stdscr.deleteln, stdscr.erase, stdscr.getbegyx,
stdscr.getbkgd, stdscr.getkey, stdscr.getmaxyx, stdscr.getbkgd, stdscr.getkey, stdscr.getmaxyx,
@ -126,6 +126,13 @@ class TestCurses(unittest.TestCase):
win.border(65, 66, 67, 68, win.border(65, 66, 67, 68,
69, [], 71, 72) 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) stdscr.clearok(1)
win4 = stdscr.derwin(2,2) win4 = stdscr.derwin(2,2)

View File

@ -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.

View File

@ -911,12 +911,19 @@ PyCursesWindow_Border(PyCursesWindowObject *self, PyObject *args)
static PyObject * static PyObject *
PyCursesWindow_Box(PyCursesWindowObject *self, PyObject *args) PyCursesWindow_Box(PyCursesWindowObject *self, PyObject *args)
{ {
PyObject *temp1, *temp2;
chtype ch1=0,ch2=0; chtype ch1=0,ch2=0;
switch(PyTuple_Size(args)){ switch(PyTuple_Size(args)){
case 0: break; case 0: break;
default: default:
if (!PyArg_ParseTuple(args,"ll;vertint,horint", &ch1, &ch2)) if (!PyArg_ParseTuple(args,"OO;verch,horch", &temp1, &temp2))
return NULL; return NULL;
if (!PyCurses_ConvertToChtype(self, temp1, &ch1)) {
return NULL;
}
if (!PyCurses_ConvertToChtype(self, temp2, &ch2)) {
return NULL;
}
} }
box(self->win,ch1,ch2); box(self->win,ch1,ch2);
Py_RETURN_NONE; Py_RETURN_NONE;
@ -2268,24 +2275,30 @@ PyCurses_GetMouse(PyObject *self)
PyErr_SetString(PyCursesError, "getmouse() returned ERR"); PyErr_SetString(PyCursesError, "getmouse() returned ERR");
return NULL; return NULL;
} }
return Py_BuildValue("(hiiil)", return Py_BuildValue("(hiiik)",
(short)event.id, (short)event.id,
event.x, event.y, event.z, (int)event.x, (int)event.y, (int)event.z,
(long) event.bstate); (unsigned long) event.bstate);
} }
static PyObject * static PyObject *
PyCurses_UngetMouse(PyObject *self, PyObject *args) PyCurses_UngetMouse(PyObject *self, PyObject *args)
{ {
MEVENT event; MEVENT event;
short id;
int x, y, z;
unsigned long bstate;
PyCursesInitialised; PyCursesInitialised;
if (!PyArg_ParseTuple(args, "hiiil", if (!PyArg_ParseTuple(args, "hiiik",
&event.id, &id, &x, &y, &z, &bstate))
&event.x, &event.y, &event.z,
(int *) &event.bstate))
return NULL; return NULL;
event.id = id;
event.x = x;
event.y = y;
event.z = z;
event.bstate = bstate;
return PyCursesCheckERR(ungetmouse(&event), "ungetmouse"); return PyCursesCheckERR(ungetmouse(&event), "ungetmouse");
} }
#endif #endif
@ -2669,14 +2682,15 @@ PyCurses_MouseInterval(PyObject *self, PyObject *args)
static PyObject * static PyObject *
PyCurses_MouseMask(PyObject *self, PyObject *args) PyCurses_MouseMask(PyObject *self, PyObject *args)
{ {
int newmask; unsigned long newmask;
mmask_t oldmask, availmask; mmask_t oldmask, availmask;
PyCursesInitialised; PyCursesInitialised;
if (!PyArg_ParseTuple(args,"i;mousemask",&newmask)) if (!PyArg_ParseTuple(args,"k;mousemask",&newmask))
return NULL; return NULL;
availmask = mousemask(newmask, &oldmask); availmask = mousemask((mmask_t)newmask, &oldmask);
return Py_BuildValue("(ll)", (long)availmask, (long)oldmask); return Py_BuildValue("(kk)",
(unsigned long)availmask, (unsigned long)oldmask);
} }
#endif #endif