mirror of
https://github.com/ultrajson/ultrajson.git
synced 2024-11-23 04:12:13 +01:00
Raise JSONDecodeError in place of ValueError on failed decode (#498)
So as to match the behaviour of Python's json library. Fixes #497
This commit is contained in:
parent
d5b701f209
commit
316d384f41
@ -38,6 +38,7 @@ http://www.opensource.apple.com/source/tcl/tcl-14/tcl/license.terms
|
||||
|
||||
#include <Python.h>
|
||||
#include <ultrajson.h>
|
||||
#include "ujson.h"
|
||||
|
||||
|
||||
//#define PRINTMARK() fprintf(stderr, "%s: MARK(%d)\n", __FILE__, __LINE__)
|
||||
@ -187,7 +188,7 @@ PyObject* JSONToObj(PyObject* self, PyObject *args, PyObject *kwargs)
|
||||
/*
|
||||
FIXME: It's possible to give a much nicer error message here with actual failing element in input etc*/
|
||||
|
||||
PyErr_Format (PyExc_ValueError, "%s", decoder.errorStr);
|
||||
PyErr_Format (JSONDecodeError, "%s", decoder.errorStr);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
|
@ -38,6 +38,7 @@ http://www.opensource.apple.com/source/tcl/tcl-14/tcl/license.terms
|
||||
|
||||
#include <Python.h>
|
||||
#include "version.h"
|
||||
#include "ujson.h"
|
||||
|
||||
/* objToJSON */
|
||||
PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs);
|
||||
@ -51,6 +52,8 @@ PyObject* objToJSONFile(PyObject* self, PyObject *args, PyObject *kwargs);
|
||||
/* JSONFileToObj */
|
||||
PyObject* JSONFileToObj(PyObject* self, PyObject *args, PyObject *kwargs);
|
||||
|
||||
PyObject* JSONDecodeError;
|
||||
|
||||
|
||||
#define ENCODER_HELP_TEXT "Use ensure_ascii=false to output UTF-8. " \
|
||||
"Set encode_html_chars=True to encode < > & as unicode escape sequences. "\
|
||||
@ -188,5 +191,15 @@ PyMODINIT_FUNC PyInit_ujson(void)
|
||||
PyErr_Clear();
|
||||
#endif
|
||||
|
||||
JSONDecodeError = PyErr_NewException("ujson.JSONDecodeError", PyExc_ValueError, NULL);
|
||||
Py_XINCREF(JSONDecodeError);
|
||||
if (PyModule_AddObject(module, "JSONDecodeError", JSONDecodeError) < 0)
|
||||
{
|
||||
Py_XDECREF(JSONDecodeError);
|
||||
Py_CLEAR(JSONDecodeError);
|
||||
Py_DECREF(module);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return module;
|
||||
}
|
||||
|
1
python/ujson.h
Normal file
1
python/ujson.h
Normal file
@ -0,0 +1 @@
|
||||
extern PyObject* JSONDecodeError;
|
@ -555,46 +555,46 @@ def test_decode_numeric_int_exp(test_input):
|
||||
@pytest.mark.parametrize(
|
||||
"test_input, expected",
|
||||
[
|
||||
('{{1337:""}}', ValueError), # broken dict key type leak test
|
||||
('{{"key":"}', ValueError), # broken dict leak test
|
||||
('{{"key":"}', ValueError), # broken dict leak test
|
||||
("[[[true", ValueError), # broken list leak test
|
||||
('{{1337:""}}', ujson.JSONDecodeError), # broken dict key type leak test
|
||||
('{{"key":"}', ujson.JSONDecodeError), # broken dict leak test
|
||||
('{{"key":"}', ujson.JSONDecodeError), # broken dict leak test
|
||||
("[[[true", ujson.JSONDecodeError), # broken list leak test
|
||||
],
|
||||
)
|
||||
def test_decode_range_raises(test_input, expected):
|
||||
for x in range(1000):
|
||||
with pytest.raises(ValueError):
|
||||
with pytest.raises(expected):
|
||||
ujson.decode(test_input)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_input, expected",
|
||||
[
|
||||
("fdsa sda v9sa fdsa", ValueError), # jibberish
|
||||
("[", ValueError), # broken array start
|
||||
("{", ValueError), # broken object start
|
||||
("]", ValueError), # broken array end
|
||||
("}", ValueError), # broken object end
|
||||
('{"one":1,}', ValueError), # object trailing comma fail
|
||||
('"TESTING', ValueError), # string unterminated
|
||||
('"TESTING\\"', ValueError), # string bad escape
|
||||
("tru", ValueError), # true broken
|
||||
("fa", ValueError), # false broken
|
||||
("n", ValueError), # null broken
|
||||
("{{{{31337}}}}", ValueError), # dict with no key
|
||||
('{{{{"key"}}}}', ValueError), # dict with no colon or value
|
||||
('{{{{"key":}}}}', ValueError), # dict with no value
|
||||
("[31337,]", ValueError), # array trailing comma fail
|
||||
("[,31337]", ValueError), # array leading comma fail
|
||||
("[,]", ValueError), # array only comma fail
|
||||
("[]]", ValueError), # array unmatched bracket fail
|
||||
("18446744073709551616", ValueError), # too big value
|
||||
("-90223372036854775809", ValueError), # too small value
|
||||
("18446744073709551616", ValueError), # very too big value
|
||||
("-90223372036854775809", ValueError), # very too small value
|
||||
("{}\n\t a", ValueError), # with trailing non whitespaces
|
||||
("[18446744073709551616]", ValueError), # array with big int
|
||||
('{"age", 44}', ValueError), # read bad object syntax
|
||||
("fdsa sda v9sa fdsa", ujson.JSONDecodeError), # jibberish
|
||||
("[", ujson.JSONDecodeError), # broken array start
|
||||
("{", ujson.JSONDecodeError), # broken object start
|
||||
("]", ujson.JSONDecodeError), # broken array end
|
||||
("}", ujson.JSONDecodeError), # broken object end
|
||||
('{"one":1,}', ujson.JSONDecodeError), # object trailing comma fail
|
||||
('"TESTING', ujson.JSONDecodeError), # string unterminated
|
||||
('"TESTING\\"', ujson.JSONDecodeError), # string bad escape
|
||||
("tru", ujson.JSONDecodeError), # true broken
|
||||
("fa", ujson.JSONDecodeError), # false broken
|
||||
("n", ujson.JSONDecodeError), # null broken
|
||||
("{{{{31337}}}}", ujson.JSONDecodeError), # dict with no key
|
||||
('{{{{"key"}}}}', ujson.JSONDecodeError), # dict with no colon or value
|
||||
('{{{{"key":}}}}', ujson.JSONDecodeError), # dict with no value
|
||||
("[31337,]", ujson.JSONDecodeError), # array trailing comma fail
|
||||
("[,31337]", ujson.JSONDecodeError), # array leading comma fail
|
||||
("[,]", ujson.JSONDecodeError), # array only comma fail
|
||||
("[]]", ujson.JSONDecodeError), # array unmatched bracket fail
|
||||
("18446744073709551616", ujson.JSONDecodeError), # too big value
|
||||
("-90223372036854775809", ujson.JSONDecodeError), # too small value
|
||||
("18446744073709551616", ujson.JSONDecodeError), # very too big value
|
||||
("-90223372036854775809", ujson.JSONDecodeError), # very too small value
|
||||
("{}\n\t a", ujson.JSONDecodeError), # with trailing non whitespaces
|
||||
("[18446744073709551616]", ujson.JSONDecodeError), # array with big int
|
||||
('{"age", 44}', ujson.JSONDecodeError), # read bad object syntax
|
||||
],
|
||||
)
|
||||
def test_decode_raises(test_input, expected):
|
||||
@ -605,8 +605,8 @@ def test_decode_raises(test_input, expected):
|
||||
@pytest.mark.parametrize(
|
||||
"test_input, expected",
|
||||
[
|
||||
("[", ValueError), # array depth too big
|
||||
("{", ValueError), # object depth too big
|
||||
("[", ujson.JSONDecodeError), # array depth too big
|
||||
("{", ujson.JSONDecodeError), # object depth too big
|
||||
],
|
||||
)
|
||||
def test_decode_raises_for_long_input(test_input, expected):
|
||||
@ -614,6 +614,10 @@ def test_decode_raises_for_long_input(test_input, expected):
|
||||
ujson.decode(test_input * (1024 * 1024))
|
||||
|
||||
|
||||
def test_decode_exception_is_value_error():
|
||||
assert issubclass(ujson.JSONDecodeError, ValueError)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_input, expected",
|
||||
[
|
||||
|
Loading…
Reference in New Issue
Block a user