Skip to content

Commit 7bfcfcf

Browse files
miss-islingtonsobolevnerlend-aasland
authored
[3.12] gh-110365: Fix error overwrite in termios.tcsetattr (GH-110366) (#110389)
(cherry picked from commit 2bbbab2) Co-authored-by: Nikita Sobolev <[email protected]> Co-authored-by: Erlend E. Aasland <[email protected]>
1 parent 4da8c1b commit 7bfcfcf

File tree

2 files changed

+28
-13
lines changed

2 files changed

+28
-13
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix :func:`termios.tcsetattr` bug that was overwritting existing errors
2+
during parsing integers from ``term`` list.

Modules/termios.c

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -183,17 +183,25 @@ termios_tcsetattr_impl(PyObject *module, int fd, int when, PyObject *term)
183183
return PyErr_SetFromErrno(state->TermiosError);
184184
}
185185

186-
mode.c_iflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 0));
187-
mode.c_oflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 1));
188-
mode.c_cflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 2));
189-
mode.c_lflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 3));
190-
speed_t ispeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 4));
191-
speed_t ospeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 5));
192-
PyObject *cc = PyList_GetItem(term, 6);
193-
if (PyErr_Occurred()) {
194-
return NULL;
195-
}
196-
186+
speed_t ispeed, ospeed;
187+
#define SET_FROM_LIST(TYPE, VAR, LIST, N) do { \
188+
PyObject *item = PyList_GET_ITEM(LIST, N); \
189+
long num = PyLong_AsLong(item); \
190+
if (num == -1 && PyErr_Occurred()) { \
191+
return NULL; \
192+
} \
193+
VAR = (TYPE)num; \
194+
} while (0)
195+
196+
SET_FROM_LIST(tcflag_t, mode.c_iflag, term, 0);
197+
SET_FROM_LIST(tcflag_t, mode.c_oflag, term, 1);
198+
SET_FROM_LIST(tcflag_t, mode.c_cflag, term, 2);
199+
SET_FROM_LIST(tcflag_t, mode.c_lflag, term, 3);
200+
SET_FROM_LIST(speed_t, ispeed, term, 4);
201+
SET_FROM_LIST(speed_t, ospeed, term, 5);
202+
#undef SET_FROM_LIST
203+
204+
PyObject *cc = PyList_GET_ITEM(term, 6);
197205
if (!PyList_Check(cc) || PyList_Size(cc) != NCCS) {
198206
PyErr_Format(PyExc_TypeError,
199207
"tcsetattr: attributes[6] must be %d element list",
@@ -208,8 +216,13 @@ termios_tcsetattr_impl(PyObject *module, int fd, int when, PyObject *term)
208216

209217
if (PyBytes_Check(v) && PyBytes_Size(v) == 1)
210218
mode.c_cc[i] = (cc_t) * PyBytes_AsString(v);
211-
else if (PyLong_Check(v))
212-
mode.c_cc[i] = (cc_t) PyLong_AsLong(v);
219+
else if (PyLong_Check(v)) {
220+
long num = PyLong_AsLong(v);
221+
if (num == -1 && PyErr_Occurred()) {
222+
return NULL;
223+
}
224+
mode.c_cc[i] = (cc_t)num;
225+
}
213226
else {
214227
PyErr_SetString(PyExc_TypeError,
215228
"tcsetattr: elements of attributes must be characters or integers");

0 commit comments

Comments
 (0)