Index: Modules/_json.c =================================================================== --- Modules/_json.c (révision 76635) +++ Modules/_json.c (copie de travail) @@ -442,9 +442,22 @@ Py_ssize_t next = begin; int has_unicode = 0; char *buf = PyString_AS_STRING(pystr); - PyObject *chunks = PyList_New(0); - if (chunks == NULL) { - goto bail; + PyObject *chunks = NULL; + PyObject *chunk = NULL; + +#define APPEND_OLD_CHUNK \ + if (chunk != NULL) { \ + if (chunks == NULL) { \ + chunks = PyList_New(0); \ + if (chunks == NULL) { \ + goto bail; \ + } \ + } \ + if (PyList_Append(chunks, chunk)) { \ + Py_DECREF(chunk); \ + goto bail; \ + } \ + Py_CLEAR(chunk); \ } if (end < 0 || len <= end) { PyErr_SetString(PyExc_ValueError, "end is out of bounds"); @@ -453,7 +466,6 @@ while (1) { /* Find the end of the string or the next escape */ Py_UNICODE c = 0; - PyObject *chunk = NULL; for (next = end; next < len; next++) { c = (unsigned char)buf[next]; if (c == '"' || c == '\\') { @@ -473,6 +485,7 @@ } /* Pick up this chunk if it's not zero length */ if (next != end) { + APPEND_OLD_CHUNK PyObject *strchunk = PyString_FromStringAndSize(&buf[end], next - end); if (strchunk == NULL) { goto bail; @@ -487,11 +500,6 @@ else { chunk = strchunk; } - if (PyList_Append(chunks, chunk)) { - Py_DECREF(chunk); - goto bail; - } - Py_DECREF(chunk); } next++; if (c == '"') { @@ -596,6 +604,7 @@ if (c > 0x7f) { has_unicode = 1; } + APPEND_OLD_CHUNK if (has_unicode) { chunk = PyUnicode_FromUnicode(&c, 1); if (chunk == NULL) { @@ -609,18 +618,22 @@ goto bail; } } - if (PyList_Append(chunks, chunk)) { - Py_DECREF(chunk); + } + + if (chunks == NULL) { + if (chunk != NULL) + rval = chunk; + else + rval = PyString_FromStringAndSize("", 0); + } + else { + APPEND_OLD_CHUNK + rval = join_list_string(chunks); + if (rval == NULL) { goto bail; } - Py_DECREF(chunk); + Py_CLEAR(chunks); } - - rval = join_list_string(chunks); - if (rval == NULL) { - goto bail; - } - Py_CLEAR(chunks); *next_end_ptr = end; return rval; bail: @@ -927,18 +940,26 @@ */ char *str = PyString_AS_STRING(pystr); Py_ssize_t end_idx = PyString_GET_SIZE(pystr) - 1; - PyObject *rval; - PyObject *pairs; + PyObject *rval = NULL; + PyObject *pairs = NULL; PyObject *item; PyObject *key = NULL; PyObject *val = NULL; char *encoding = PyString_AS_STRING(s->encoding); int strict = PyObject_IsTrue(s->strict); + int has_pairs_hook = (s->pairs_hook != Py_None); Py_ssize_t next_idx; - pairs = PyList_New(0); - if (pairs == NULL) - return NULL; + if (has_pairs_hook) { + pairs = PyList_New(0); + if (pairs == NULL) + return NULL; + } + else { + rval = PyDict_New(); + if (rval == NULL) + return NULL; + } /* skip whitespace after { */ while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; @@ -970,16 +991,24 @@ if (val == NULL) goto bail; - item = PyTuple_Pack(2, key, val); - if (item == NULL) - goto bail; - Py_CLEAR(key); - Py_CLEAR(val); - if (PyList_Append(pairs, item) == -1) { + if (has_pairs_hook) { + item = PyTuple_Pack(2, key, val); + if (item == NULL) + goto bail; + Py_CLEAR(key); + Py_CLEAR(val); + if (PyList_Append(pairs, item) == -1) { + Py_DECREF(item); + goto bail; + } Py_DECREF(item); - goto bail; } - Py_DECREF(item); + else { + if (PyDict_SetItem(rval, key, val) < 0) + goto bail; + Py_CLEAR(key); + Py_CLEAR(val); + } idx = next_idx; /* skip whitespace before } or , */ @@ -1016,12 +1045,6 @@ return val; } - rval = PyObject_CallFunctionObjArgs((PyObject *)(&PyDict_Type), - pairs, NULL); - if (rval == NULL) - goto bail; - Py_CLEAR(pairs); - /* if object_hook is not None: rval = object_hook(rval) */ if (s->object_hook != Py_None) { val = PyObject_CallFunctionObjArgs(s->object_hook, rval, NULL); @@ -1034,6 +1057,7 @@ *next_idx_ptr = idx + 1; return rval; bail: + Py_XDECREF(rval); Py_XDECREF(key); Py_XDECREF(val); Py_XDECREF(pairs);