Skip to content

Commit

Permalink
Fix for overflowing long causing invalid json
Browse files Browse the repository at this point in the history
This was caused by checking for "__json__" using PyObject_HasAttrString
which clears the error set by a previous long overflow. Thus this was dependent
on the order of processing of dict items, which explains why it was
seemingly random as the dict items are likely ordered by a hash of
the key.

This fixes GH224 and GH240.
  • Loading branch information
Jahaja committed Feb 4, 2017
1 parent 870ee48 commit 409c6d4
Showing 1 changed file with 29 additions and 14 deletions.
43 changes: 29 additions & 14 deletions python/objToJSON.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,21 @@ static void *PyDateToINT64(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size
return NULL;
}

static int PyHasAttrStringPreserveErr(PyObject *obj, const char *attr)
{
int res;
PyObject *excType = NULL, *excValue, *excTraceback;

if (!PyErr_Occurred())
return PyObject_HasAttrString(obj, "__json__");

PyErr_Fetch(&excType, &excValue, &excTraceback);
res = PyObject_HasAttrString(obj, "__json__");
PyErr_Restore(excType, excValue, excTraceback);

return res;
}

static int Tuple_iterNext(JSOBJ obj, JSONTypeContext *tc)
{
PyObject *item;
Expand Down Expand Up @@ -471,21 +486,21 @@ static int Dict_iterNext(JSOBJ obj, JSONTypeContext *tc)
GET_TC(tc)->itemName = PyUnicode_AsUTF8String (GET_TC(tc)->itemName);
}
else
if (!PyString_Check(GET_TC(tc)->itemName))
{
GET_TC(tc)->itemName = PyObject_Str(GET_TC(tc)->itemName);
if (!PyString_Check(GET_TC(tc)->itemName))
{
GET_TC(tc)->itemName = PyObject_Str(GET_TC(tc)->itemName);
#if PY_MAJOR_VERSION >= 3
itemNameTmp = GET_TC(tc)->itemName;
GET_TC(tc)->itemName = PyUnicode_AsUTF8String (GET_TC(tc)->itemName);
Py_DECREF(itemNameTmp);
itemNameTmp = GET_TC(tc)->itemName;
GET_TC(tc)->itemName = PyUnicode_AsUTF8String (GET_TC(tc)->itemName);
Py_DECREF(itemNameTmp);
#endif
}
else
{
Py_INCREF(GET_TC(tc)->itemName);
}
PRINTMARK();
return 1;
}
else
{
Py_INCREF(GET_TC(tc)->itemName);
}
PRINTMARK();
return 1;
}

static void Dict_iterEnd(JSOBJ obj, JSONTypeContext *tc)
Expand Down Expand Up @@ -728,7 +743,7 @@ static void Object_beginTypeContext (JSOBJ _obj, JSONTypeContext *tc, JSONObject
return;
}
else
if (PyString_Check(obj) && !PyObject_HasAttrString(obj, "__json__"))
if (PyString_Check(obj) && !PyHasAttrStringPreserveErr(obj, "__json__"))
{
PRINTMARK();
pc->PyTypeToJSON = PyStringToUTF8; tc->type = JT_UTF8;
Expand Down

0 comments on commit 409c6d4

Please sign in to comment.