diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2015-11-04 20:33:07 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2015-11-04 20:33:07 (GMT) |
commit | 710cd34bdbaddda5c5f03033c068e44a1bac7f21 (patch) | |
tree | 3d46562db71c1e242fd2fdf498715b79ba4925e9 /Objects/odictobject.c | |
parent | b45b7b213742261c95324766027d44e30656b8e7 (diff) | |
download | cpython-710cd34bdbaddda5c5f03033c068e44a1bac7f21.zip cpython-710cd34bdbaddda5c5f03033c068e44a1bac7f21.tar.gz cpython-710cd34bdbaddda5c5f03033c068e44a1bac7f21.tar.bz2 |
Issue #25449: Fixed a crash and leaking NULL in repr() of OrderedDict that
was mutated by direct calls of dict methods.
Diffstat (limited to 'Objects/odictobject.c')
-rw-r--r-- | Objects/odictobject.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/Objects/odictobject.c b/Objects/odictobject.c index d6189a3..28537a8 100644 --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -1462,7 +1462,6 @@ odict_repr(PyODictObject *self) { int i; _Py_IDENTIFIER(items); - Py_ssize_t count = -1; PyObject *pieces = NULL, *result = NULL; const char *classname; @@ -1481,6 +1480,7 @@ odict_repr(PyODictObject *self) } if (PyODict_CheckExact(self)) { + Py_ssize_t count = 0; _ODictNode *node; pieces = PyList_New(PyODict_SIZE(self)); if (pieces == NULL) @@ -1499,8 +1499,19 @@ odict_repr(PyODictObject *self) if (pair == NULL) goto Done; - PyList_SET_ITEM(pieces, ++count, pair); /* steals reference */ + if (count < PyList_GET_SIZE(pieces)) + PyList_SET_ITEM(pieces, count, pair); /* steals reference */ + else { + if (PyList_Append(pieces, pair) < 0) { + Py_DECREF(pair); + goto Done; + } + Py_DECREF(pair); + } + count++; } + if (count < PyList_GET_SIZE(pieces)) + PyList_GET_SIZE(pieces) = count; } else { PyObject *items = _PyObject_CallMethodIdObjArgs((PyObject *)self, |