diff --git a/lib/ultrajsondec.c b/lib/ultrajsondec.c index 5304604..bccb0aa 100644 --- a/lib/ultrajsondec.c +++ b/lib/ultrajsondec.c @@ -79,6 +79,8 @@ static JSOBJ SetError( struct DecoderState *ds, int offset, const char *message) static FASTCALL_ATTR JSOBJ FASTCALL_MSVC decodeDouble(struct DecoderState *ds) { int processed_characters_count; + /* Prevent int overflow if ds->end - ds->start is too large. See check_decode_decimal_no_int_overflow() + inside tests/test_ujson.py for an example where this check is necessary. */ int len = ((size_t) (ds->end - ds->start) < (size_t) INT_MAX) ? (int) (ds->end - ds->start) : INT_MAX; double value = dconv_s2d(ds->dec->s2d, ds->start, len, &processed_characters_count); ds->lastType = JT_DOUBLE; diff --git a/tests/test_ujson.py b/tests/test_ujson.py index c605691..41d17d6 100644 --- a/tests/test_ujson.py +++ b/tests/test_ujson.py @@ -1124,9 +1124,15 @@ def test_separators_errors(separators, expected_exception): ujson.dumps({"a": 0, "b": 1}, separators=separators) -def test_decode_decimal_no_int_overflow(): - # Takes a while because the string is large; feel free to comment out or remove - ujson.decode(r'[0.123456789,"{}"]'.format("a" * (2**32 - 5))) +""" +The following checks are not part of the standard test suite. +They can be run manually as follows: +python -c 'from tests.test_ujson import check_foo; check_foo()' +""" +def check_decode_decimal_no_int_overflow(): + # Requires enough free RAM to hold a ~4GB string in memory + decoded = ujson.decode(r'[0.123456789,"{}"]'.format("a" * (2**32 - 5))) + assert decoded[0] == 0.123456789 """