diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2015-06-02 05:35:13 (GMT) |
---|---|---|
committer | Eric Snow <ericsnowcurrently@gmail.com> | 2015-06-02 05:35:13 (GMT) |
commit | b952ab43f281bafd8d4fce4e84b41e655a3e7c23 (patch) | |
tree | 89cb0f122e8820d48835d9787487d59dae1932d9 /Objects/odictobject.c | |
parent | d1719756098b282ad703b899ebcb57eeeb0167c2 (diff) | |
download | cpython-b952ab43f281bafd8d4fce4e84b41e655a3e7c23.zip cpython-b952ab43f281bafd8d4fce4e84b41e655a3e7c23.tar.gz cpython-b952ab43f281bafd8d4fce4e84b41e655a3e7c23.tar.bz2 |
Issue #24359: Check for changed OrderedDict size during iteration.
Diffstat (limited to 'Objects/odictobject.c')
-rw-r--r-- | Objects/odictobject.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/Objects/odictobject.c b/Objects/odictobject.c index b91bd68..b44a61e 100644 --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -1796,6 +1796,7 @@ typedef struct { PyObject_HEAD int kind; PyODictObject *di_odict; + Py_ssize_t di_size; PyObject *di_current; PyObject *di_result; /* reusable result tuple for iteritems */ } odictiterobject; @@ -1835,6 +1836,14 @@ odictiter_nextkey(odictiterobject *di) if (di->di_current == NULL) goto done; /* We're already done. */ + /* Check for unsupported changes. */ + if (di->di_size != PyODict_SIZE(di->di_odict)) { + PyErr_SetString(PyExc_RuntimeError, + "OrderedDict changed size during iteration"); + di->di_size = -1; /* Make this state sticky */ + return NULL; + } + /* Get the key. */ node = _odict_find_node(di->di_odict, di->di_current); if (node == NULL) { @@ -2033,6 +2042,7 @@ odictiter_new(PyODictObject *od, int kind) node = reversed ? _odict_LAST(od) : _odict_FIRST(od); di->di_current = node ? _odictnode_KEY(node) : NULL; Py_XINCREF(di->di_current); + di->di_size = PyODict_SIZE(od); di->di_odict = od; Py_INCREF(od); |