mirror of
https://github.com/ultrajson/ultrajson.git
synced 2024-11-24 01:04:19 +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:
parent
028279a1bb
commit
824a42bf8c
@ -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)
|
||||
{
|
||||
|
@ -565,29 +565,34 @@ class UltraJSONTests(TestCase):
|
||||
def test_version(self):
|
||||
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:
|
||||
|
Loading…
Reference in New Issue
Block a user