summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Hettinger <rhettinger@users.noreply.github.com>2017-09-25 09:15:53 (GMT)
committerGitHub <noreply@github.com>2017-09-25 09:15:53 (GMT)
commit8110dbd470f3daa4de58dda66d360e3c26d3b94f (patch)
tree1f5c602bcfbeedbc3cf2e6cfc86a5f44611b12a3
parente6d9fcbb8d0c325e57df08ae8781aafedb71eca2 (diff)
downloadcpython-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.c48
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);