bpo-31505: Fix an assertion failure in json, in case _json.make_encoder() received a bad encoder() argument. (#3643)

This commit is contained in:
Oren Milman 2017-09-24 12:07:12 +03:00 committed by Serhiy Storchaka
parent 039b25d8fd
commit 2b382dd612
3 changed files with 36 additions and 3 deletions

View File

@ -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", b"\xCD\x7D\x3D\x4E\x12\x4C\xF9\x79\xD7\x52\xBA\x82\xF2\x27\x4A\x7D\xA0\xCA\x75",
None) 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_bad_bool_args(self):
def test(name): def test(name):
self.json.encoder.JSONEncoder(**{name: BadBool()}).encode({'a': 1}) self.json.encoder.JSONEncoder(**{name: BadBool()}).encode({'a': 1})

View File

@ -0,0 +1,2 @@
Fix an assertion failure in `json`, in case `_json.make_encoder()` received
a bad `encoder()` argument. Patch by Oren Milman.

View File

@ -1429,10 +1429,20 @@ static PyObject *
encoder_encode_string(PyEncoderObject *s, PyObject *obj) encoder_encode_string(PyEncoderObject *s, PyObject *obj)
{ {
/* Return the JSON representation of a string */ /* Return the JSON representation of a string */
if (s->fast_encode) PyObject *encoded;
if (s->fast_encode) {
return s->fast_encode(NULL, obj); 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 static int