Kaydet (Commit) 558be283 authored tarafından Guido van Rossum's avatar Guido van Rossum

Make sure the objects returned by __getinitargs__() are kept alive (in

the memo) to avoid a certain kind of nasty crash.  (Not easily
reproducable because it requires a later call to __getinitargs__() to
return a tuple that happens to be allocated at the same address.)
üst 86c052e8
...@@ -195,11 +195,28 @@ def _deepcopy_dict(x, memo): ...@@ -195,11 +195,28 @@ def _deepcopy_dict(x, memo):
return y return y
d[types.DictionaryType] = _deepcopy_dict d[types.DictionaryType] = _deepcopy_dict
def _keep_alive(x, memo):
"""Keeps a reference to the object x in the memo.
Because we remember objects by their id, we have
to assure that possibly temporary objects are kept
alive by referencing them.
We store a reference at the id of the memo, which should
normally not be used unless someone tries to deepcopy
the memo itself...
"""
try:
memo[id(memo)].append(x)
except KeyError:
# aha, this is the first one :-)
memo[id(memo)]=[x]
def _deepcopy_inst(x, memo): def _deepcopy_inst(x, memo):
if hasattr(x, '__deepcopy__'): if hasattr(x, '__deepcopy__'):
return x.__deepcopy__() return x.__deepcopy__()
if hasattr(x, '__getinitargs__'): if hasattr(x, '__getinitargs__'):
args = x.__getinitargs__() args = x.__getinitargs__()
_keep_alive(args, memo)
args = deepcopy(args, memo) args = deepcopy(args, memo)
else: else:
args = () args = ()
...@@ -207,6 +224,7 @@ def _deepcopy_inst(x, memo): ...@@ -207,6 +224,7 @@ def _deepcopy_inst(x, memo):
memo[id(x)] = y memo[id(x)] = y
if hasattr(x, '__getstate__'): if hasattr(x, '__getstate__'):
state = x.__getstate__() state = x.__getstate__()
_keep_alive(state, memo)
else: else:
state = x.__dict__ state = x.__dict__
state = deepcopy(state, memo) state = deepcopy(state, memo)
......
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