]> 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/test/json_tests/test_decode.py
Misc/ACKS
Misc/NEWS
Modules/_json.c

index 15a427f719b29f88e83b6ee7d971c2b297063f16..a3d7b08883771e9d99c1dd4b89bd280140ca30c6 100644 (file)
@@ -70,5 +70,9 @@ class TestDecode:
         msg = 'escape'
         self.assertRaisesRegex(ValueError, msg, self.loads, s)
 
+    def test_negative_index(self):
+        d = self.json.JSONDecoder()
+        self.assertRaises(ValueError, d.raw_decode, 'a'*42, -50000)
+
 class TestPyDecode(TestDecode, PyTest): pass
 class TestCDecode(TestDecode, CTest): pass
index b95047497e1e2d5d7647254c7dfb31dbc54c4e20..a932074975461e3b0e476be8dfca78874d7f2226 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1139,6 +1139,7 @@ Frank Visser
 Johannes Vogel
 Martijn Vries
 Sjoerd de Vries
+Guido Vranken
 Niki W. Waibel
 Wojtek Walczak
 Charles Waldman
index 3913f94956fc19f72199885f7b6360363b2efc5a..e44219a9d7f428ef7c1fa0825a87b24cc256f7b0 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ What's New in Python 3.2.6?
 Library
 -------
 
+- Fix arbitrary memory access in JSONDecoder.raw_decode with a negative second
+  parameter. Bug reported by Guido Vranken.
+
 - Issue #21082: In os.makedirs, do not set the process-wide umask. Note this
   changes behavior of makedirs when exist_ok=True.
 
index 01436b6950a04bc0cb1d325794a3614243ee62f4..5bd52cb78988e6f7855936f8800cef747cd65078 100644 (file)
@@ -930,7 +930,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;
     }