Commit 796cc6e3 authored by Thomas Perl's avatar Thomas Perl Committed by Inada Naoki

bpo-36452: dictiter: track maximum iteration count (GH-12596)

parent 738cb42a
...@@ -470,6 +470,15 @@ class DictTest(unittest.TestCase): ...@@ -470,6 +470,15 @@ class DictTest(unittest.TestCase):
for i in d: for i in d:
d[i+1] = 1 d[i+1] = 1
def test_mutating_iteration_delete(self):
# change dict content during iteration
d = {}
d[0] = 0
with self.assertRaises(RuntimeError):
for i in d:
del d[0]
d[1] = 1
def test_mutating_lookup(self): def test_mutating_lookup(self):
# changing dict during a lookup (issue #14417) # changing dict during a lookup (issue #14417)
class NastyKey: class NastyKey:
......
Changing `dict` keys during iteration will now be detected in certain corner cases where the number of keys isn't changed (but they keys themselves are), and a `RuntimeError` will be raised.
\ No newline at end of file
...@@ -3543,6 +3543,12 @@ dictiter_iternextkey(dictiterobject *di) ...@@ -3543,6 +3543,12 @@ dictiter_iternextkey(dictiterobject *di)
goto fail; goto fail;
key = entry_ptr->me_key; key = entry_ptr->me_key;
} }
// We found an element (key), but did not expect it
if (di->len == 0) {
PyErr_SetString(PyExc_RuntimeError,
"dictionary keys changed during iteration");
goto fail;
}
di->di_pos = i+1; di->di_pos = i+1;
di->len--; di->len--;
Py_INCREF(key); Py_INCREF(key);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment