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

This commit is contained in:
Thomas Perl 2019-03-28 07:03:25 +01:00 committed by Inada Naoki
parent 738cb42a14
commit 796cc6e3ad
3 changed files with 16 additions and 0 deletions

View File

@ -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:

View File

@ -0,0 +1 @@
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.

View File

@ -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);