mirror of
https://github.com/ultrajson/ultrajson.git
synced 2024-04-19 16:34:04 +02:00
Fix segmentation faults when handling unserialisable objects
Errors during `__repr__` itself as well as ones during the conversion to a bytes object were not handled, resulting in NULL pointer dereferencing. Cf. #382
This commit is contained in:
parent
779949896e
commit
b3f8754c8a
|
@ -670,8 +670,15 @@ DEFAULT:
|
|||
PyErr_Clear();
|
||||
|
||||
objRepr = PyObject_Repr(obj);
|
||||
PyObject* str = PyUnicode_AsEncodedString(objRepr, "utf-8", "~E~");
|
||||
PyErr_Format (PyExc_TypeError, "%s is not JSON serializable", PyBytes_AsString(str));
|
||||
if (!objRepr)
|
||||
{
|
||||
goto INVALID;
|
||||
}
|
||||
PyObject* str = PyUnicode_AsEncodedString(objRepr, "utf-8", "strict");
|
||||
if (str)
|
||||
{
|
||||
PyErr_Format (PyExc_TypeError, "%s is not JSON serializable", PyBytes_AsString(str));
|
||||
}
|
||||
Py_XDECREF(str);
|
||||
Py_DECREF(objRepr);
|
||||
|
||||
|
|
|
@ -636,8 +636,14 @@ def test_dumps(test_input, expected):
|
|||
|
||||
|
||||
class SomeObject:
|
||||
def __init__(self, message, exception=None):
|
||||
self._message = message
|
||||
self._exception = exception
|
||||
|
||||
def __repr__(self):
|
||||
return "Some Object"
|
||||
if self._exception:
|
||||
raise self._exception
|
||||
return self._message
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
@ -645,13 +651,16 @@ class SomeObject:
|
|||
[
|
||||
(set(), TypeError, "set() is not JSON serializable"),
|
||||
({1, 2, 3}, TypeError, "{1, 2, 3} is not JSON serializable"),
|
||||
(SomeObject(), TypeError, "Some Object is not JSON serializable"),
|
||||
(SomeObject("Some Object"), TypeError, "Some Object is not JSON serializable"),
|
||||
(SomeObject("\ud800"), UnicodeEncodeError, None),
|
||||
(SomeObject(None, KeyboardInterrupt), KeyboardInterrupt, None),
|
||||
],
|
||||
)
|
||||
def test_dumps_raises(test_input, expected_exception, expected_message):
|
||||
with pytest.raises(expected_exception) as e:
|
||||
ujson.dumps(test_input)
|
||||
assert str(e.value) == expected_message
|
||||
if expected_message:
|
||||
assert str(e.value) == expected_message
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
Loading…
Reference in New Issue