From: Oren Milman Date: Sun, 24 Sep 2017 09:07:12 +0000 (+0300) Subject: bpo-31505: Fix an assertion failure in json, in case _json.make_encoder() received... X-Git-Tag: v3.7.0a2~127 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2b382dd6121bb1e4b75470fb3ef8555665df3eb6;p=python bpo-31505: Fix an assertion failure in json, in case _json.make_encoder() received a bad encoder() argument. (#3643) --- diff --git a/Lib/test/test_json/test_speedups.py b/Lib/test/test_json/test_speedups.py index 56f1882001..5dad692087 100644 --- a/Lib/test/test_json/test_speedups.py +++ b/Lib/test/test_json/test_speedups.py @@ -36,6 +36,27 @@ class TestEncode(CTest): b"\xCD\x7D\x3D\x4E\x12\x4C\xF9\x79\xD7\x52\xBA\x82\xF2\x27\x4A\x7D\xA0\xCA\x75", None) + def test_bad_str_encoder(self): + # Issue #31505: There shouldn't be an assertion failure in case + # c_make_encoder() receives a bad encoder() argument. + def bad_encoder1(*args): + return None + enc = self.json.encoder.c_make_encoder(None, lambda obj: str(obj), + bad_encoder1, None, ': ', ', ', + False, False, False) + with self.assertRaises(TypeError): + enc('spam', 4) + with self.assertRaises(TypeError): + enc({'spam': 42}, 4) + + def bad_encoder2(*args): + 1/0 + enc = self.json.encoder.c_make_encoder(None, lambda obj: str(obj), + bad_encoder2, None, ': ', ', ', + False, False, False) + with self.assertRaises(ZeroDivisionError): + enc('spam', 4) + def test_bad_bool_args(self): def test(name): self.json.encoder.JSONEncoder(**{name: BadBool()}).encode({'a': 1}) diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-09-18-12-07-39.bpo-31505.VomaFa.rst b/Misc/NEWS.d/next/Core and Builtins/2017-09-18-12-07-39.bpo-31505.VomaFa.rst new file mode 100644 index 0000000000..bad9e51aaf --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-09-18-12-07-39.bpo-31505.VomaFa.rst @@ -0,0 +1,2 @@ +Fix an assertion failure in `json`, in case `_json.make_encoder()` received +a bad `encoder()` argument. Patch by Oren Milman. diff --git a/Modules/_json.c b/Modules/_json.c index 769696d9d6..13218a6ecc 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -1429,10 +1429,20 @@ static PyObject * encoder_encode_string(PyEncoderObject *s, PyObject *obj) { /* Return the JSON representation of a string */ - if (s->fast_encode) + PyObject *encoded; + + if (s->fast_encode) { return s->fast_encode(NULL, obj); - else - return PyObject_CallFunctionObjArgs(s->encoder, obj, NULL); + } + encoded = PyObject_CallFunctionObjArgs(s->encoder, obj, NULL); + if (encoded != NULL && !PyUnicode_Check(encoded)) { + PyErr_Format(PyExc_TypeError, + "encoder() must return a string, not %.80s", + Py_TYPE(encoded)->tp_name); + Py_DECREF(encoded); + return NULL; + } + return encoded; } static int