From: Oren Milman Date: Sat, 26 Aug 2017 12:27:50 +0000 (+0300) Subject: [3.6] bpo-28261: Prevent raising SystemError where PyArg_ParseTuple is used to parse... X-Git-Tag: v3.6.3rc1~130 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8e67981fc8e1bf3cb9774b5fbf4a39b8d65ba4ff;p=python [3.6] bpo-28261: Prevent raising SystemError where PyArg_ParseTuple is used to parse non-args. (#3210) --- diff --git a/Lib/test/test_audioop.py b/Lib/test/test_audioop.py index 8f34d72427..9baa62ad45 100644 --- a/Lib/test/test_audioop.py +++ b/Lib/test/test_audioop.py @@ -405,6 +405,10 @@ class TestAudioop(unittest.TestCase): self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None, 30, 10)[0], expected[w]) + self.assertRaises(TypeError, audioop.ratecv, b'', 1, 1, 8000, 8000, 42) + self.assertRaises(TypeError, audioop.ratecv, + b'', 1, 1, 8000, 8000, (1, (42,))) + def test_reverse(self): for w in 1, 2, 3, 4: self.assertEqual(audioop.reverse(b'', w), b'') diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 8c91ad2ad8..6a2c7a9fca 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -3410,6 +3410,7 @@ class IncrementalNewlineDecoderTest(unittest.TestCase): decoder = codecs.getincrementaldecoder("utf-8")() decoder = self.IncrementalNewlineDecoder(decoder, translate=True) self.check_newline_decoding_utf8(decoder) + self.assertRaises(TypeError, decoder.setstate, 42) def test_newline_bytes(self): # Issue 5433: Excessive optimization in IncrementalNewlineDecoder diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index bc8d11efa5..61adcf6050 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -538,6 +538,12 @@ _io_IncrementalNewlineDecoder_getstate_impl(nldecoder_object *self) _PyIO_str_getstate, NULL); if (state == NULL) return NULL; + if (!PyTuple_Check(state)) { + PyErr_SetString(PyExc_TypeError, + "illegal decoder state"); + Py_DECREF(state); + return NULL; + } if (!PyArg_ParseTuple(state, "OK", &buffer, &flag)) { Py_DECREF(state); return NULL; @@ -569,6 +575,10 @@ _io_IncrementalNewlineDecoder_setstate(nldecoder_object *self, PyObject *buffer; unsigned long long flag; + if (!PyTuple_Check(state)) { + PyErr_SetString(PyExc_TypeError, "state argument must be a tuple"); + return NULL; + } if (!PyArg_ParseTuple(state, "OK", &buffer, &flag)) return NULL; @@ -2320,6 +2330,12 @@ _io_TextIOWrapper_tell_impl(textio *self) _PyIO_str_getstate, NULL); \ if (_state == NULL) \ goto fail; \ + if (!PyTuple_Check(_state)) { \ + PyErr_SetString(PyExc_TypeError, \ + "illegal decoder state"); \ + Py_DECREF(_state); \ + goto fail; \ + } \ if (!PyArg_ParseTuple(_state, "Oi", &dec_buffer, &dec_flags)) { \ Py_DECREF(_state); \ goto fail; \ diff --git a/Modules/audioop.c b/Modules/audioop.c index dcd7788d62..d582042519 100644 --- a/Modules/audioop.c +++ b/Modules/audioop.c @@ -1293,7 +1293,7 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width, char *cp, *ncp; Py_ssize_t len; int chan, d, *prev_i, *cur_i, cur_o; - PyObject *samps, *str, *rv = NULL; + PyObject *samps, *str, *rv = NULL, *channel; int bytes_per_frame; if (!audioop_check_size(width)) @@ -1354,6 +1354,10 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width, prev_i[chan] = cur_i[chan] = 0; } else { + if (!PyTuple_Check(state)) { + PyErr_SetString(PyExc_TypeError, "state must be a tuple or None"); + goto exit; + } if (!PyArg_ParseTuple(state, "iO!;audioop.ratecv: illegal state argument", &d, &PyTuple_Type, &samps)) @@ -1364,7 +1368,13 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width, goto exit; } for (chan = 0; chan < nchannels; chan++) { - if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan), + channel = PyTuple_GetItem(samps, chan); + if (!PyTuple_Check(channel)) { + PyErr_SetString(PyExc_TypeError, + "ratecv(): illegal state argument"); + goto exit; + } + if (!PyArg_ParseTuple(channel, "ii:ratecv", &prev_i[chan], &cur_i[chan])) goto exit;