1
0
mirror of https://github.com/ultrajson/ultrajson.git synced 2024-11-24 05:12:02 +01:00

- Added support for detecting overflow scenario when a PyLong bigger than 64-bits signed is supposed to be converted to such. Now a proper Python exception is thrown

- Bumped version

- Encoder now uses JT_INVALID from client implementation to abort encoder
This commit is contained in:
Jonas Tarnstrom 2011-09-19 17:30:35 +02:00
parent 028279a1bb
commit 824a42bf8c
5 changed files with 49 additions and 23 deletions

@ -30,6 +30,9 @@ typedef struct __TypeContext
PyObject *itemValue;
PyObject *itemName;
PyObject *attrList;
JSINT64 longValue;
} TypeContext;
#define GET_TC(__ptrtc) ((TypeContext *)((__ptrtc)->prv))
@ -97,7 +100,7 @@ static void *PyIntToINT64(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_
static void *PyLongToINT64(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
{
PyObject *obj = (PyObject *) _obj;
*((JSINT64 *) outValue) = PyLong_AsLongLong (obj);
*((JSINT64 *) outValue) = GET_TC(tc)->longValue;
return NULL;
}
@ -460,8 +463,22 @@ void Object_beginTypeContext (PyObject *obj, JSONTypeContext *tc)
else
if (PyLong_Check(obj))
{
PyObject *exc;
PRINTMARK();
pc->PyTypeToJSON = PyLongToINT64; tc->type = JT_LONG;
pc->PyTypeToJSON = PyLongToINT64;
tc->type = JT_LONG;
GET_TC(tc)->longValue = PyLong_AsLongLong(obj);
exc = PyErr_Occurred();
if (exc && PyErr_ExceptionMatches(PyExc_OverflowError))
{
PRINTMARK();
tc->type = JT_INVALID;
return;
}
return;
}
else
@ -611,6 +628,7 @@ JSINT64 Object_getLongValue(JSOBJ obj, JSONTypeContext *tc)
{
JSINT64 ret;
GET_TC(tc)->PyTypeToJSON (obj, tc, &ret, NULL);
return ret;
}
@ -710,6 +728,10 @@ PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs)
ret = JSON_EncodeObject (oinput, &encoder, buffer, sizeof (buffer));
PRINTMARK();
if (PyErr_Occurred())
{
return NULL;
}
if (encoder.errorMsg)
{

@ -566,28 +566,33 @@ class UltraJSONTests(TestCase):
assert re.match(r'^\d+\.\d+(\.\d+)?$', ujson.__version__), \
"ujson.__version__ must be a string like '1.4.0'"
def test_encodeNumericOverflow(self):
try:
ujson.encode(12839128391289382193812939)
except OverflowError:
pass
else:
assert False, "expected OverflowError"
def test_encodeNumericOverflowNested(self):
for n in xrange(0, 100):
class Nested:
x = 12839128391289382193812939
nested = Nested()
try:
ujson.encode(nested)
except OverflowError:
pass
else:
assert False, "expected OverflowError"
"""
def test_decodeNumericIntFrcOverflow(self):
input = "X.Y"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntPosOverflow(self):
input = "9223372036854775807322"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeNumericIntNegOverflow(self):
input = "-9223372036854775807322"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeStringUnicodeEscape(self):
input = "\u3131"

@ -1 +1 @@
#define UJSON_VERSION "1.8"
#define UJSON_VERSION "1.9"

@ -152,7 +152,7 @@ typedef void * JSITER;
typedef struct __JSONTypeContext
{
int type;
void *prv[15];
void *prv[32];
} JSONTypeContext;
/*

@ -632,7 +632,6 @@ void encode(JSOBJ obj, JSONObjectEncoder *enc, const char *name, size_t cbName)
switch (tc.type)
{
case JT_INVALID:
SetError(obj, enc, "Could not encode object");
return;
case JT_ARRAY: