Skip to content

Commit aad7ac1

Browse files
miss-islingtonserhiy-storchaka
authored andcommitted
bpo-27666: Fixed stack corruption in curses.box() and curses.ungetmouse(). (GH-4220) (#4221)
(cherry picked from commit 4f469c0)
1 parent 1f81ea8 commit aad7ac1

File tree

3 files changed

+37
-13
lines changed

3 files changed

+37
-13
lines changed

‎Lib/test/test_curses.py‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def test_window_funcs(self):
9292
with self.subTest(meth=meth.__qualname__, args=args):
9393
meth(*args)
9494

95-
for meth in [stdscr.box, stdscr.clear, stdscr.clrtobot,
95+
for meth in [stdscr.clear, stdscr.clrtobot,
9696
stdscr.clrtoeol, stdscr.cursyncup, stdscr.delch,
9797
stdscr.deleteln, stdscr.erase, stdscr.getbegyx,
9898
stdscr.getbkgd, stdscr.getkey, stdscr.getmaxyx,
@@ -126,6 +126,13 @@ def test_window_funcs(self):
126126
win.border(65, 66, 67, 68,
127127
69, [], 71, 72)
128128

129+
win.box(65, 67)
130+
win.box('!', '_')
131+
win.box(b':', b'~')
132+
self.assertRaises(TypeError, win.box, 65, 66, 67)
133+
self.assertRaises(TypeError, win.box, 65)
134+
win.box()
135+
129136
stdscr.clearok(1)
130137

131138
win4 = stdscr.derwin(2,2)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fixed stack corruption in curses.box() and curses.ungetmouse() when the size
2+
of types chtype or mmask_t is less than the size of C long. curses.box()
3+
now accepts characters as arguments. Based on patch by Steve Fink.

‎Modules/_cursesmodule.c‎

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -912,12 +912,19 @@ PyCursesWindow_Border(PyCursesWindowObject *self, PyObject *args)
912912
static PyObject *
913913
PyCursesWindow_Box(PyCursesWindowObject *self, PyObject *args)
914914
{
915+
PyObject *temp1, *temp2;
915916
chtype ch1=0,ch2=0;
916917
switch(PyTuple_Size(args)){
917918
case 0: break;
918919
default:
919-
if (!PyArg_ParseTuple(args,"ll;vertint,horint", &ch1, &ch2))
920+
if (!PyArg_ParseTuple(args,"OO;verch,horch", &temp1, &temp2))
920921
return NULL;
922+
if (!PyCurses_ConvertToChtype(self, temp1, &ch1)) {
923+
return NULL;
924+
}
925+
if (!PyCurses_ConvertToChtype(self, temp2, &ch2)) {
926+
return NULL;
927+
}
921928
}
922929
box(self->win,ch1,ch2);
923930
Py_INCREF(Py_None);
@@ -2285,24 +2292,30 @@ PyCurses_GetMouse(PyObject *self)
22852292
PyErr_SetString(PyCursesError, "getmouse() returned ERR");
22862293
return NULL;
22872294
}
2288-
return Py_BuildValue("(hiiil)",
2295+
return Py_BuildValue("(hiiik)",
22892296
(short)event.id,
2290-
event.x, event.y, event.z,
2291-
(long) event.bstate);
2297+
(int)event.x, (int)event.y, (int)event.z,
2298+
(unsigned long) event.bstate);
22922299
}
22932300

22942301
static PyObject *
22952302
PyCurses_UngetMouse(PyObject *self, PyObject *args)
22962303
{
22972304
MEVENT event;
2305+
short id;
2306+
int x, y, z;
2307+
unsigned long bstate;
22982308

22992309
PyCursesInitialised;
2300-
if (!PyArg_ParseTuple(args, "hiiil",
2301-
&event.id,
2302-
&event.x, &event.y, &event.z,
2303-
(int *) &event.bstate))
2310+
if (!PyArg_ParseTuple(args, "hiiik",
2311+
&id, &x, &y, &z, &bstate))
23042312
return NULL;
23052313

2314+
event.id = id;
2315+
event.x = x;
2316+
event.y = y;
2317+
event.z = z;
2318+
event.bstate = bstate;
23062319
return PyCursesCheckERR(ungetmouse(&event), "ungetmouse");
23072320
}
23082321
#endif
@@ -2701,14 +2714,15 @@ PyCurses_MouseInterval(PyObject *self, PyObject *args)
27012714
static PyObject *
27022715
PyCurses_MouseMask(PyObject *self, PyObject *args)
27032716
{
2704-
int newmask;
2717+
unsigned long newmask;
27052718
mmask_t oldmask, availmask;
27062719

27072720
PyCursesInitialised;
2708-
if (!PyArg_ParseTuple(args,"i;mousemask",&newmask))
2721+
if (!PyArg_ParseTuple(args,"k;mousemask",&newmask))
27092722
return NULL;
2710-
availmask = mousemask(newmask, &oldmask);
2711-
return Py_BuildValue("(ll)", (long)availmask, (long)oldmask);
2723+
availmask = mousemask((mmask_t)newmask, &oldmask);
2724+
return Py_BuildValue("(kk)",
2725+
(unsigned long)availmask, (unsigned long)oldmask);
27122726
}
27132727
#endif
27142728

0 commit comments

Comments
 (0)