blob: 98659ce1722b9f637596abb711d6c3ece341678a [file] [log] [blame]
commit 409c6d4006fdea27e746ea397124f98c92a41a92
Author: Joakim Hamren <joakim.hamren@gmail.com>
Date: Sat Feb 4 04:21:05 2017 +0100
Fix for overflowing long causing invalid json
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.
diff --git a/python/objToJSON.c b/python/objToJSON.c
index 8133fb5..adea2f6 100644
--- a/python/objToJSON.c
+++ b/python/objToJSON.c
@@ -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;
@@ -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)
@@ -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;