]> granicus.if.org Git - python/commitdiff
in scan_once, prevent the reading of arbitrary memory when passed a negative index
authorBenjamin Peterson <benjamin@python.org>
Mon, 14 Apr 2014 02:10:38 +0000 (22:10 -0400)
committerBenjamin Peterson <benjamin@python.org>
Mon, 14 Apr 2014 02:10:38 +0000 (22:10 -0400)
Bug reported by Guido Vranken.

Lib/json/tests/test_decode.py
Misc/ACKS
Misc/NEWS
Modules/_json.c

index ffd1aa4badbc896213a6edc4413661346de11695..78d7fbb7c6c7e77ed5347ab3e5459fe7ad5f299a 100644 (file)
@@ -60,5 +60,10 @@ class TestDecode(object):
         msg = 'escape'
         self.assertRaisesRegexp(ValueError, msg, self.loads, s)
 
+    def test_negative_index(self):
+        d = self.json.JSONDecoder()
+        self.assertRaises(ValueError, d.raw_decode, 'a'*42, -50000)
+        self.assertRaises(ValueError, d.raw_decode, u'a'*42, -50000)
+
 class TestPyDecode(TestDecode, PyTest): pass
 class TestCDecode(TestDecode, CTest): pass
index 2fd7e33c9c6a1156dd86f8f251dd02706cfb3880..a6180020f9ee2485ace65e3e50ed28992e342211 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1369,6 +1369,7 @@ Pauli Virtanen
 Frank Visser
 Johannes Vogel
 Alex Volkov
+Guido Vranken
 Martijn Vries
 Sjoerd de Vries
 Niki W. Waibel
index 7fef5b5e1e4d14c09eb9b52b850279261abf33c2..79eaada0fa8aeb5fc62d70ecc1ac91473b75e80e 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -43,6 +43,9 @@ Core and Builtins
 Library
 -------
 
+- Fix arbitrary memory access in JSONDecoder.raw_decode with a negative second
+  parameter. Bug reported by Guido Vranken.
+
 - Issue #21172: isinstance check relaxed from dict to collections.Mapping.
 
 - Issue #21191: In os.fdopen, alwyas close the file descriptor when an exception
index eb4368a229aff77d64dfb510d0c626a13c0c8267..56d9ee47b9aca69efd59be200f93980d29c0bc25 100644 (file)
@@ -1468,7 +1468,10 @@ scan_once_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *n
     PyObject *res;
     char *str = PyString_AS_STRING(pystr);
     Py_ssize_t length = PyString_GET_SIZE(pystr);
-    if (idx >= length) {
+    if (idx < 0)
+        /* Compatibility with the Python version. */
+        idx += length;
+    if (idx < 0 || idx >= length) {
         PyErr_SetNone(PyExc_StopIteration);
         return NULL;
     }
@@ -1555,7 +1558,10 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_
     PyObject *res;
     Py_UNICODE *str = PyUnicode_AS_UNICODE(pystr);
     Py_ssize_t length = PyUnicode_GET_SIZE(pystr);
-    if (idx >= length) {
+    if (idx < 0)
+        /* Compatibility with Python version. */
+        idx += length;
+    if (idx < 0 || idx >= length) {
         PyErr_SetNone(PyExc_StopIteration);
         return NULL;
     }