From: Guido van Rossum Date: Wed, 20 Aug 1997 22:26:19 +0000 (+0000) Subject: Make sure the objects returned by __getinitargs__() are kept alive (in X-Git-Tag: v1.5a4~356 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=558be283bf2c3a2c405c8a404da1cfed69900226;p=python 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.) --- diff --git a/Lib/copy.py b/Lib/copy.py index 6dc781c4e0..ef5b10edd0 100644 --- a/Lib/copy.py +++ b/Lib/copy.py @@ -195,11 +195,28 @@ def _deepcopy_dict(x, memo): return y 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): if hasattr(x, '__deepcopy__'): return x.__deepcopy__() if hasattr(x, '__getinitargs__'): args = x.__getinitargs__() + _keep_alive(args, memo) args = deepcopy(args, memo) else: args = () @@ -207,6 +224,7 @@ def _deepcopy_inst(x, memo): memo[id(x)] = y if hasattr(x, '__getstate__'): state = x.__getstate__() + _keep_alive(state, memo) else: state = x.__dict__ state = deepcopy(state, memo)