Skip to content

Commit b694770

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

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
(4,4, 'a'), (5,5, 'a', curses.A_BOLD)]:
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,
@@ -125,6 +125,13 @@ def test_window_funcs(self):
125125
win.border(65, 66, 67, 68,
126126
69, [], 71, 72)
127127

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

130137
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
@@ -639,12 +639,19 @@ PyCursesWindow_Border(PyCursesWindowObject *self, PyObject *args)
639639
static PyObject *
640640
PyCursesWindow_Box(PyCursesWindowObject *self, PyObject *args)
641641
{
642+
PyObject *temp1, *temp2;
642643
chtype ch1=0,ch2=0;
643644
switch(PyTuple_Size(args)){
644645
case 0: break;
645646
default:
646-
if (!PyArg_ParseTuple(args,"ll;vertint,horint", &ch1, &ch2))
647+
if (!PyArg_ParseTuple(args,"OO;verch,horch", &temp1, &temp2))
647648
return NULL;
649+
if (!PyCurses_ConvertToChtype(self, temp1, &ch1)) {
650+
return NULL;
651+
}
652+
if (!PyCurses_ConvertToChtype(self, temp2, &ch2)) {
653+
return NULL;
654+
}
648655
}
649656
box(self->win,ch1,ch2);
650657
Py_INCREF(Py_None);
@@ -1826,24 +1833,30 @@ PyCurses_GetMouse(PyObject *self)
18261833
PyErr_SetString(PyCursesError, "getmouse() returned ERR");
18271834
return NULL;
18281835
}
1829-
return Py_BuildValue("(hiiil)",
1836+
return Py_BuildValue("(hiiik)",
18301837
(short)event.id,
1831-
event.x, event.y, event.z,
1832-
(long) event.bstate);
1838+
(int)event.x, (int)event.y, (int)event.z,
1839+
(unsigned long) event.bstate);
18331840
}
18341841

18351842
static PyObject *
18361843
PyCurses_UngetMouse(PyObject *self, PyObject *args)
18371844
{
18381845
MEVENT event;
1846+
short id;
1847+
int x, y, z;
1848+
unsigned long bstate;
18391849

18401850
PyCursesInitialised;
1841-
if (!PyArg_ParseTuple(args, "hiiil",
1842-
&event.id,
1843-
&event.x, &event.y, &event.z,
1844-
(int *) &event.bstate))
1851+
if (!PyArg_ParseTuple(args, "hiiik",
1852+
&id, &x, &y, &z, &bstate))
18451853
return NULL;
18461854

1855+
event.id = id;
1856+
event.x = x;
1857+
event.y = y;
1858+
event.z = z;
1859+
event.bstate = bstate;
18471860
return PyCursesCheckERR(ungetmouse(&event), "ungetmouse");
18481861
}
18491862
#endif
@@ -2200,14 +2213,15 @@ PyCurses_MouseInterval(PyObject *self, PyObject *args)
22002213
static PyObject *
22012214
PyCurses_MouseMask(PyObject *self, PyObject *args)
22022215
{
2203-
int newmask;
2216+
unsigned long newmask;
22042217
mmask_t oldmask, availmask;
22052218

22062219
PyCursesInitialised;
2207-
if (!PyArg_ParseTuple(args,"i;mousemask",&newmask))
2220+
if (!PyArg_ParseTuple(args,"k;mousemask",&newmask))
22082221
return NULL;
2209-
availmask = mousemask(newmask, &oldmask);
2210-
return Py_BuildValue("(ll)", (long)availmask, (long)oldmask);
2222+
availmask = mousemask((mmask_t)newmask, &oldmask);
2223+
return Py_BuildValue("(kk)",
2224+
(unsigned long)availmask, (unsigned long)oldmask);
22112225
}
22122226
#endif
22132227

0 commit comments

Comments
 (0)