diff options
author | Raymond Hettinger <rhettinger@users.noreply.github.com> | 2017-09-25 09:15:53 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-25 09:15:53 (GMT) |
commit | 8110dbd470f3daa4de58dda66d360e3c26d3b94f (patch) | |
tree | 1f5c602bcfbeedbc3cf2e6cfc86a5f44611b12a3 | |
parent | e6d9fcbb8d0c325e57df08ae8781aafedb71eca2 (diff) | |
download | cpython-8110dbd470f3daa4de58dda66d360e3c26d3b94f.zip cpython-8110dbd470f3daa4de58dda66d360e3c26d3b94f.tar.gz cpython-8110dbd470f3daa4de58dda66d360e3c26d3b94f.tar.bz2 |
bpo-26491 Defer DECREFs until enumobject is in a consistent state (#3747)
-rw-r--r-- | Objects/enumobject.c | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/Objects/enumobject.c b/Objects/enumobject.c index 3eb1736..154d901 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -103,6 +103,8 @@ enum_next_long(enumobject *en, PyObject* next_item) PyObject *result = en->en_result; PyObject *next_index; PyObject *stepped_up; + PyObject *old_index; + PyObject *old_item; if (en->en_longindex == NULL) { en->en_longindex = PyLong_FromSsize_t(PY_SSIZE_T_MAX); @@ -118,15 +120,19 @@ enum_next_long(enumobject *en, PyObject* next_item) if (result->ob_refcnt == 1) { Py_INCREF(result); - Py_DECREF(PyTuple_GET_ITEM(result, 0)); - Py_DECREF(PyTuple_GET_ITEM(result, 1)); - } else { - result = PyTuple_New(2); - if (result == NULL) { - Py_DECREF(next_index); - Py_DECREF(next_item); - return NULL; - } + old_index = PyTuple_GET_ITEM(result, 0); + old_item = PyTuple_GET_ITEM(result, 1); + PyTuple_SET_ITEM(result, 0, next_index); + PyTuple_SET_ITEM(result, 1, next_item); + Py_DECREF(old_index); + Py_DECREF(old_item); + return result; + } + result = PyTuple_New(2); + if (result == NULL) { + Py_DECREF(next_index); + Py_DECREF(next_item); + return NULL; } PyTuple_SET_ITEM(result, 0, next_index); PyTuple_SET_ITEM(result, 1, next_item); @@ -140,6 +146,8 @@ enum_next(enumobject *en) PyObject *next_item; PyObject *result = en->en_result; PyObject *it = en->en_sit; + PyObject *old_index; + PyObject *old_item; next_item = (*Py_TYPE(it)->tp_iternext)(it); if (next_item == NULL) @@ -157,15 +165,19 @@ enum_next(enumobject *en) if (result->ob_refcnt == 1) { Py_INCREF(result); - Py_DECREF(PyTuple_GET_ITEM(result, 0)); - Py_DECREF(PyTuple_GET_ITEM(result, 1)); - } else { - result = PyTuple_New(2); - if (result == NULL) { - Py_DECREF(next_index); - Py_DECREF(next_item); - return NULL; - } + old_index = PyTuple_GET_ITEM(result, 0); + old_item = PyTuple_GET_ITEM(result, 1); + PyTuple_SET_ITEM(result, 0, next_index); + PyTuple_SET_ITEM(result, 1, next_item); + Py_DECREF(old_index); + Py_DECREF(old_item); + return result; + } + result = PyTuple_New(2); + if (result == NULL) { + Py_DECREF(next_index); + Py_DECREF(next_item); + return NULL; } PyTuple_SET_ITEM(result, 0, next_index); PyTuple_SET_ITEM(result, 1, next_item); |