diff options
Diffstat (limited to 'simplejson/_speedups.c')
-rw-r--r-- | simplejson/_speedups.c | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/simplejson/_speedups.c b/simplejson/_speedups.c index 0b2d81c..65cf444 100644 --- a/simplejson/_speedups.c +++ b/simplejson/_speedups.c @@ -10,6 +10,7 @@ #define PyString_AS_STRING PyBytes_AS_STRING #define PyString_FromStringAndSize PyBytes_FromStringAndSize #define PyInt_Check(obj) 0 +#define PyInt_CheckExact(obj) 0 #define JSON_UNICHR Py_UCS4 #define JSON_InternFromString PyUnicode_InternFromString #define JSON_Intern_GET_SIZE PyUnicode_GET_SIZE @@ -660,7 +661,19 @@ encoder_stringify_key(PyEncoderObject *s, PyObject *key) return _encoded_const(key); } else if (PyInt_Check(key) || PyLong_Check(key)) { - return PyObject_Str(key); + if (!(PyInt_CheckExact(key) || PyLong_CheckExact(key))) { + /* See #118, do not trust custom str/repr */ + PyObject *tmp = PyObject_CallFunctionObjArgs((PyObject *)&PyLong_Type, key, NULL); + if (tmp == NULL) { + return NULL; + } + PyObject *res = PyObject_Str(tmp); + Py_DECREF(tmp); + return res; + } + else { + return PyObject_Str(key); + } } else if (s->use_decimal && PyObject_TypeCheck(key, (PyTypeObject *)s->Decimal)) { return PyObject_Str(key); @@ -2637,7 +2650,7 @@ encoder_init(PyObject *self, PyObject *args, PyObject *kwds) s->tuple_as_array = PyObject_IsTrue(tuple_as_array); if (PyInt_Check(int_as_string_bitcount) || PyLong_Check(int_as_string_bitcount)) { static const unsigned int long_long_bitsize = SIZEOF_LONG_LONG * 8; - int int_as_string_bitcount_val = PyLong_AsLong(int_as_string_bitcount); + int int_as_string_bitcount_val = (int)PyLong_AsLong(int_as_string_bitcount); if (int_as_string_bitcount_val > 0 && int_as_string_bitcount_val < long_long_bitsize) { s->max_long_size = PyLong_FromUnsignedLongLong(1ULL << int_as_string_bitcount_val); s->min_long_size = PyLong_FromLongLong(-1LL << int_as_string_bitcount_val); @@ -2800,7 +2813,19 @@ encoder_encode_float(PyEncoderObject *s, PyObject *obj) } } /* Use a better float format here? */ - return PyObject_Repr(obj); + if (PyFloat_CheckExact(obj)) { + return PyObject_Repr(obj); + } + else { + /* See #118, do not trust custom str/repr */ + PyObject *tmp = PyObject_CallFunctionObjArgs((PyObject *)&PyFloat_Type, obj, NULL); + if (tmp == NULL) { + return NULL; + } + PyObject *res = PyObject_Repr(tmp); + Py_DECREF(tmp); + return res; + } } static PyObject * @@ -2840,7 +2865,21 @@ encoder_listencode_obj(PyEncoderObject *s, JSON_Accu *rval, PyObject *obj, Py_ss rv = _steal_accumulate(rval, encoded); } else if (PyInt_Check(obj) || PyLong_Check(obj)) { - PyObject *encoded = PyObject_Str(obj); + PyObject *encoded; + if (PyInt_CheckExact(obj) || PyLong_CheckExact(obj)) { + encoded = PyObject_Str(obj); + } + else { + /* See #118, do not trust custom str/repr */ + PyObject *tmp = PyObject_CallFunctionObjArgs((PyObject *)&PyLong_Type, obj, NULL); + if (tmp == NULL) { + encoded = NULL; + } + else { + encoded = PyObject_Str(tmp); + Py_DECREF(tmp); + } + } if (encoded != NULL) { encoded = maybe_quote_bigint(s, encoded, obj); if (encoded == NULL) |