]> 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:52:09 +0000 (17:52 +0300)
committerSerhiy Storchaka <storchaka@gmail.com>
Sun, 28 Jun 2015 14:52:09 +0000 (17:52 +0300)
functions of the audioop module.

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

index 01ed18d1c107a65b55c6b2c056c160b69872ab12..8f34d72427e1833f12c2194cdb006be60e166692 100644 (file)
@@ -273,6 +273,16 @@ class TestAudioop(unittest.TestCase):
         # 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),
index 02b129a508359d8535d2bd474837f9c6bf625de0..d1f6242b5f482002425877c649aa888085019980 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -60,6 +60,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #24456: Fixed possible buffer over-read in adpcm2lin() and lin2adpcm()
+  functions of the audioop module.
+
 - Issue #24336: The contextmanager decorator now works with functions with
   keyword arguments called "func" and "self".  Patch by Martin Panter.
 
index 0358147f92a4c94bdd1814925d35e5b35a22e171..5efed0c661ca9e67b0999b8ff0bcf30868802699 100644 (file)
@@ -1615,23 +1615,30 @@ audioop_lin2adpcm_impl(PyModuleDef *module, Py_buffer *fragment, int width, PyOb
     if (!audioop_check_parameters(fragment->len, width))
         return NULL;
 
-    str = PyBytes_FromStringAndSize(NULL, fragment->len/(width*2));
-    if (str == NULL)
-        return NULL;
-    ncp = (signed char *)PyBytes_AsString(str);
-
     /* Decode state, should have (value, step) */
     if ( state == Py_None ) {
         /* First time, it seems. Set defaults */
         valpred = 0;
         index = 0;
-    } else if (!PyTuple_Check(state)) {
+    }
+    else if (!PyTuple_Check(state)) {
         PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
-        goto exit;
-    } else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
-        goto exit;
+        return NULL;
+    }
+    else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
+        return NULL;
+    }
+    else if (valpred >= 0x8000 || valpred < -0x8000 ||
+             (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) {
+        PyErr_SetString(PyExc_ValueError, "bad state");
+        return NULL;
     }
 
+    str = PyBytes_FromStringAndSize(NULL, fragment->len/(width*2));
+    if (str == NULL)
+        return NULL;
+    ncp = (signed char *)PyBytes_AsString(str);
+
     step = stepsizeTable[index];
     bufferstep = 1;
 
@@ -1706,8 +1713,6 @@ audioop_lin2adpcm_impl(PyModuleDef *module, Py_buffer *fragment, int width, PyOb
         bufferstep = !bufferstep;
     }
     rv = Py_BuildValue("(O(ii))", str, valpred, index);
-
-  exit:
     Py_DECREF(str);
     return rv;
 }
@@ -1742,11 +1747,19 @@ audioop_adpcm2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width, PyOb
         /* First time, it seems. Set defaults */
         valpred = 0;
         index = 0;
-    } else if (!PyTuple_Check(state)) {
+    }
+    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))
+    }
+    else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
+        return NULL;
+    }
+    else if (valpred >= 0x8000 || valpred < -0x8000 ||
+             (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) {
+        PyErr_SetString(PyExc_ValueError, "bad state");
         return NULL;
+    }
 
     if (fragment->len > (PY_SSIZE_T_MAX/2)/width) {
         PyErr_SetString(PyExc_MemoryError,