summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2015-06-02 05:35:13 (GMT)
committerEric Snow <ericsnowcurrently@gmail.com>2015-06-02 05:35:13 (GMT)
commitb952ab43f281bafd8d4fce4e84b41e655a3e7c23 (patch)
tree89cb0f122e8820d48835d9787487d59dae1932d9 /Objects
parentd1719756098b282ad703b899ebcb57eeeb0167c2 (diff)
downloadcpython-b952ab43f281bafd8d4fce4e84b41e655a3e7c23.zip
cpython-b952ab43f281bafd8d4fce4e84b41e655a3e7c23.tar.gz
cpython-b952ab43f281bafd8d4fce4e84b41e655a3e7c23.tar.bz2
Issue #24359: Check for changed OrderedDict size during iteration.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/odictobject.c10
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);