From: Benjamin Peterson Date: Mon, 14 Apr 2014 02:31:42 +0000 (-0400) Subject: merge 3.3 X-Git-Tag: v3.4.1rc1~101 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=584f5cbf16980f21c58bf7ce7e451e022355fa3d;p=python merge 3.3 --- 584f5cbf16980f21c58bf7ce7e451e022355fa3d diff --cc Lib/test/test_json/test_decode.py index 35c02de88c,17245ebc48..591b2e253d --- a/Lib/test/test_json/test_decode.py +++ b/Lib/test/test_json/test_decode.py @@@ -70,26 -70,9 +70,30 @@@ class TestDecode msg = 'escape' self.assertRaisesRegex(ValueError, msg, self.loads, s) + def test_invalid_input_type(self): + msg = 'the JSON object must be str' + for value in [1, 3.14, b'bytes', b'\xff\x00', [], {}, None]: + self.assertRaisesRegex(TypeError, msg, self.loads, value) + with self.assertRaisesRegex(TypeError, msg): + self.json.load(BytesIO(b'[1,2,3]')) + + def test_string_with_utf8_bom(self): + # see #18958 + bom_json = "[1,2,3]".encode('utf-8-sig').decode('utf-8') + with self.assertRaises(ValueError) as cm: + self.loads(bom_json) + self.assertIn('BOM', str(cm.exception)) + with self.assertRaises(ValueError) as cm: + self.json.load(StringIO(bom_json)) + self.assertIn('BOM', str(cm.exception)) + # make sure that the BOM is not detected in the middle of a string + bom_in_str = '"{}"'.format(''.encode('utf-8-sig').decode('utf-8')) + 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 --cc Misc/NEWS index 74c5e50cdd,2ca47f047b..6fc6e2fbd6 --- a/Misc/NEWS +++ b/Misc/NEWS @@@ -27,35 -13,11 +27,38 @@@ Core and Builtin 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. + +- Issue #21171: Fixed undocumented filter API of the rot13 codec. + Patch by Berker Peksag. + +- Issue #21172: isinstance check relaxed from dict to collections.Mapping. + +- Issue #21155: asyncio.EventLoop.create_unix_server() now raises a ValueError + if path and sock are specified at the same time. + +- Issue #21149: Improved thread-safety in logging cleanup during interpreter + shutdown. Thanks to Devin Jeanpierre for the patch. + +- Issue #20145: `assertRaisesRegex` and `assertWarnsRegex` now raise a + TypeError if the second argument is not a string or compiled regex. + +- Issue #21058: Fix a leak of file descriptor in + :func:`tempfile.NamedTemporaryFile`, close the file descriptor if + :func:`io.open` fails + +- Issue #21013: Enhance ssl.create_default_context() when used for server side + sockets to provide better security by default. + - Issue #20633: Replace relative import by absolute import. +- Issue #20980: Stop wrapping exception when using ThreadPool. + - Issue #21082: In os.makedirs, do not set the process-wide umask. Note this changes behavior of makedirs when exist_ok=True. diff --cc Modules/_json.c index 125101fa7c,ec980c93fa..7d627cb2c5 --- a/Modules/_json.c +++ b/Modules/_json.c @@@ -941,8 -975,11 +941,11 @@@ scan_once_unicode(PyScannerObject *s, P 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) { - PyErr_SetNone(PyExc_StopIteration); + raise_stop_iteration(idx); return NULL; }