diff options
author | Ezio Melotti <ezio.melotti@gmail.com> | 2011-05-07 14:40:23 (GMT) |
---|---|---|
committer | Ezio Melotti <ezio.melotti@gmail.com> | 2011-05-07 14:40:23 (GMT) |
commit | cec464951e06dd9388352590eb1f17b9aa3d68a5 (patch) | |
tree | e9f8449b949cab39476f57c9b68670b5b2578940 /Modules/_json.c | |
parent | 5ae6c42f52c650dc317dd5f0ecab8d5087c44872 (diff) | |
download | cpython-cec464951e06dd9388352590eb1f17b9aa3d68a5.zip cpython-cec464951e06dd9388352590eb1f17b9aa3d68a5.tar.gz cpython-cec464951e06dd9388352590eb1f17b9aa3d68a5.tar.bz2 |
#12017: Fix segfault in json.loads() while decoding highly-nested objects using the C accelerations.
Diffstat (limited to 'Modules/_json.c')
-rw-r--r-- | Modules/_json.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/Modules/_json.c b/Modules/_json.c index 7a1fabd..4b4ef89 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -1488,6 +1488,7 @@ scan_once_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *n Returns a new PyObject representation of the term. */ + PyObject *res; char *str = PyString_AS_STRING(pystr); Py_ssize_t length = PyString_GET_SIZE(pystr); if (idx >= length) { @@ -1503,10 +1504,20 @@ scan_once_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *n next_idx_ptr); case '{': /* object */ - return _parse_object_str(s, pystr, idx + 1, next_idx_ptr); + if (Py_EnterRecursiveCall(" while decoding a JSON object " + "from a byte string")) + return NULL; + res = _parse_object_str(s, pystr, idx + 1, next_idx_ptr); + Py_LeaveRecursiveCall(); + return res; case '[': /* array */ - return _parse_array_str(s, pystr, idx + 1, next_idx_ptr); + if (Py_EnterRecursiveCall(" while decoding a JSON array " + "from a byte string")) + return NULL; + res = _parse_array_str(s, pystr, idx + 1, next_idx_ptr); + Py_LeaveRecursiveCall(); + return res; case 'n': /* null */ if ((idx + 3 < length) && str[idx + 1] == 'u' && str[idx + 2] == 'l' && str[idx + 3] == 'l') { @@ -1564,6 +1575,7 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ Returns a new PyObject representation of the term. */ + PyObject *res; Py_UNICODE *str = PyUnicode_AS_UNICODE(pystr); Py_ssize_t length = PyUnicode_GET_SIZE(pystr); if (idx >= length) { @@ -1578,10 +1590,20 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ next_idx_ptr); case '{': /* object */ - return _parse_object_unicode(s, pystr, idx + 1, next_idx_ptr); + if (Py_EnterRecursiveCall(" while decoding a JSON object " + "from a unicode string")) + return NULL; + res = _parse_object_unicode(s, pystr, idx + 1, next_idx_ptr); + Py_LeaveRecursiveCall(); + return res; case '[': /* array */ - return _parse_array_unicode(s, pystr, idx + 1, next_idx_ptr); + if (Py_EnterRecursiveCall(" while decoding a JSON array " + "from a unicode string")) + return NULL; + res = _parse_array_unicode(s, pystr, idx + 1, next_idx_ptr); + Py_LeaveRecursiveCall(); + return res; case 'n': /* null */ if ((idx + 3 < length) && str[idx + 1] == 'u' && str[idx + 2] == 'l' && str[idx + 3] == 'l') { |