]> granicus.if.org Git - python/commitdiff
[3.6] bpo-28261: Prevent raising SystemError where PyArg_ParseTuple is used to parse...
authorOren Milman <orenmn@gmail.com>
Sat, 26 Aug 2017 12:27:50 +0000 (15:27 +0300)
committerSerhiy Storchaka <storchaka@gmail.com>
Sat, 26 Aug 2017 12:27:50 +0000 (15:27 +0300)
Lib/test/test_audioop.py
Lib/test/test_io.py
Modules/_io/textio.c
Modules/audioop.c

index 8f34d72427e1833f12c2194cdb006be60e166692..9baa62ad45c04531a84989c5d12e378be9ed75bd 100644 (file)
@@ -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'')
index 8c91ad2ad8aa1c09f0ead1917df56bd614cd6115..6a2c7a9fca4fadabc710feef6129e8e683f525de 100644 (file)
@@ -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
index bc8d11efa5258cc15e791e1bbeb76026326efa98..61adcf60508e2fde246d550e9eaed7fd01468f96 100644 (file)
@@ -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; \
index dcd7788d6218620295b99ce9f3ff64c946f00f0b..d58204251913a8664abb523864e61c625adabda9 100644 (file)
@@ -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;