]> granicus.if.org Git - python/commitdiff
Issue #24456: Fixed possible buffer over-read in adpcm2lin() and lin2adpcm()
authorSerhiy Storchaka <storchaka@gmail.com>
Sun, 28 Jun 2015 14:51:40 +0000 (17:51 +0300)
committerSerhiy Storchaka <storchaka@gmail.com>
Sun, 28 Jun 2015 14:51:40 +0000 (17:51 +0300)
functions of the audioop module.  Fixed SystemError when the state is not a
tuple.  Fixed possible memory leak.

Lib/test/test_audioop.py
Misc/NEWS
Modules/audioop.c

index ceaf2a3325b9eda76c2b772d48764a76fefc1028..4af73500ea41aa0d613d4d3dea277e4144e64665 100644 (file)
@@ -210,6 +210,21 @@ class TestAudioop(unittest.TestCase):
             self.assertEqual(audioop.lin2adpcm(b'\0' * w * 10, w, None),
                              (b'\0' * 5, (0, 0)))
 
+    def test_invalid_adpcm_state(self):
+        # state must be a tuple or None, not an integer
+        self.assertRaises(TypeError, audioop.adpcm2lin, b'\0', 1, 555)
+        self.assertRaises(TypeError, audioop.lin2adpcm, b'\0', 1, 555)
+        # Issues #24456, #24457: index out of range
+        self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0, -1))
+        self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0, 89))
+        self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0, -1))
+        self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0, 89))
+        # value out of range
+        self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (-0x8001, 0))
+        self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0x8000, 0))
+        self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (-0x8001, 0))
+        self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0x8000, 0))
+
     def test_lin2alaw(self):
         self.assertEqual(audioop.lin2alaw(datas[1], 1),
                          b'\xd5\x87\xa4\x24\xaa\x2a\x5a')
index 1496398bb130a654f365706254c8cab971903b49..9418ad257dabd5bb0a13e258c50953e061aeea8f 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -30,6 +30,10 @@ Core and Builtins
 Library
 -------
 
+- Issue #24456: Fixed possible buffer over-read in adpcm2lin() and lin2adpcm()
+  functions of the audioop module.  Fixed SystemError when the state is not a
+  tuple.  Fixed possible memory leak.
+
 - Issue #24481: Fix possible memory corruption with large profiler info strings
   in hotshot.
 
index 0282c7e94113bb6a24d0dee41b130007ae91d617..4d3b679015058ea310706750956cad893bcccc08 100644 (file)
@@ -1420,18 +1420,29 @@ audioop_lin2adpcm(PyObject *self, PyObject *args)
     if (!audioop_check_parameters(len, size))
         return NULL;
 
-    str = PyString_FromStringAndSize(NULL, len/(size*2));
-    if ( str == 0 )
-        return 0;
-    ncp = (signed char *)PyString_AsString(str);
-
     /* Decode state, should have (value, step) */
     if ( state == Py_None ) {
         /* First time, it seems. Set defaults */
         valpred = 0;
         index = 0;
-    } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
+    }
+    else if (!PyTuple_Check(state)) {
+        PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
+        return NULL;
+    }
+    else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
+        return NULL;
+    }
+    else if (valpred >= 0x8000 || valpred < -0x8000 ||
+             (size_t)index >= sizeof(stepsizeTable)/sizeof(stepsizeTable[0])) {
+        PyErr_SetString(PyExc_ValueError, "bad state");
+        return NULL;
+    }
+
+    str = PyString_FromStringAndSize(NULL, len/(size*2));
+    if ( str == 0 )
         return 0;
+    ncp = (signed char *)PyString_AsString(str);
 
     step = stepsizeTable[index];
     bufferstep = 1;
@@ -1529,8 +1540,19 @@ audioop_adpcm2lin(PyObject *self, PyObject *args)
         /* First time, it seems. Set defaults */
         valpred = 0;
         index = 0;
-    } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
-        return 0;
+    }
+    else if (!PyTuple_Check(state)) {
+        PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
+        return NULL;
+    }
+    else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
+        return NULL;
+    }
+    else if (valpred >= 0x8000 || valpred < -0x8000 ||
+             (size_t)index >= sizeof(stepsizeTable)/sizeof(stepsizeTable[0])) {
+        PyErr_SetString(PyExc_ValueError, "bad state");
+        return NULL;
+    }
 
     if (len > (INT_MAX/2)/size) {
         PyErr_SetString(PyExc_MemoryError,