bpo-35615: Fix crashes when copying a Weak{Key,Value}Dictionary. (GH-11384)

Protect dict iterations by wrapping them with _IterationGuard in the
following methods:

- WeakValueDictionary.copy()
- WeakValueDictionary.__deepcopy__()
- WeakKeyDictionary.copy()
- WeakKeyDictionary.__deepcopy__()
This commit is contained in:
Fish 2019-02-07 14:51:59 -05:00 committed by Antoine Pitrou
parent df8d2cde63
commit 96d37dbcd2
3 changed files with 105 additions and 16 deletions

View file

@ -171,10 +171,11 @@ class WeakValueDictionary(_collections_abc.MutableMapping):
if self._pending_removals:
self._commit_removals()
new = WeakValueDictionary()
for key, wr in self.data.items():
o = wr()
if o is not None:
new[key] = o
with _IterationGuard(self):
for key, wr in self.data.items():
o = wr()
if o is not None:
new[key] = o
return new
__copy__ = copy
@ -184,10 +185,11 @@ class WeakValueDictionary(_collections_abc.MutableMapping):
if self._pending_removals:
self._commit_removals()
new = self.__class__()
for key, wr in self.data.items():
o = wr()
if o is not None:
new[deepcopy(key, memo)] = o
with _IterationGuard(self):
for key, wr in self.data.items():
o = wr()
if o is not None:
new[deepcopy(key, memo)] = o
return new
def get(self, key, default=None):
@ -408,10 +410,11 @@ class WeakKeyDictionary(_collections_abc.MutableMapping):
def copy(self):
new = WeakKeyDictionary()
for key, value in self.data.items():
o = key()
if o is not None:
new[o] = value
with _IterationGuard(self):
for key, value in self.data.items():
o = key()
if o is not None:
new[o] = value
return new
__copy__ = copy
@ -419,10 +422,11 @@ class WeakKeyDictionary(_collections_abc.MutableMapping):
def __deepcopy__(self, memo):
from copy import deepcopy
new = self.__class__()
for key, value in self.data.items():
o = key()
if o is not None:
new[o] = deepcopy(value, memo)
with _IterationGuard(self):
for key, value in self.data.items():
o = key()
if o is not None:
new[o] = deepcopy(value, memo)
return new
def get(self, key, default=None):