diff --git a/Lib/test/test_json/test_decode.py b/Lib/test/test_json/test_decode.py index 35c02de88cc..591b2e253df 100644 --- a/Lib/test/test_json/test_decode.py +++ b/Lib/test/test_json/test_decode.py @@ -91,5 +91,9 @@ class TestDecode: self.assertEqual(self.loads(bom_in_str), '\ufeff') self.assertEqual(self.json.load(StringIO(bom_in_str)), '\ufeff') + 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 diff --git a/Misc/ACKS b/Misc/ACKS index 437aa461dc3..463d752037a 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1373,6 +1373,7 @@ Johannes Vogel Alex Volkov Martijn Vries Sjoerd de Vries +Guido Vranken Niki W. Waibel Wojtek Walczak Charles Waldman diff --git a/Misc/NEWS b/Misc/NEWS index a8da8ab2050..a363a14cc10 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -34,6 +34,9 @@ Core and Builtins Library ------- +- Fix arbitrary memory access in JSONDecoder.raw_decode with a negative second + parameter. Bug reported by Guido Vranken. + - Issue #21169: getpass now handles non-ascii characters that the input stream encoding cannot encode by re-encoding using the replace error handler. diff --git a/Modules/_json.c b/Modules/_json.c index 125101fa7c3..7d627cb2c54 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -941,7 +941,10 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ kind = PyUnicode_KIND(pystr); length = PyUnicode_GET_LENGTH(pystr); - if (idx >= length) { + if (idx < 0) + /* Compatibility with Python version. */ + idx += length; + if (idx < 0 || idx >= length) { raise_stop_iteration(idx); return NULL; }