Use-after-free while pickling dicts · Issue #92930 · python/cpython (original) (raw)

Skip to content

Provide feedback

Saved searches

Use saved searches to filter your results more quickly

Sign up

@sweeneyde

Description

@sweeneyde

Found here, but this crash is unrelated, so opening a new issue.

The following could be simplified, but it crashes because PyDict_Next creates borrowed references.

import pickle from random import getrandbits

class Bad: def eq(self, other): if not ENABLED: return False break_things() return getrandbits(4) == 0 def hash(self): return getrandbits(1) def reduce(self): break_things() return (Bad, (), ()) def setstate(self, *args): break_things() def del(self): break_things() def getattr(self): break_things()

def break_things(): if getrandbits(6) == 0: collection.clear()

TRIALS = 10_000 SIZE = 50

for i in range(TRIALS): try: ENABLED = False collection = {Bad():Bad() for _ in range(SIZE)} for bad in collection: bad.bad = bad bad.collection = collection ENABLED = True pickle.loads(pickle.dumps(collection)) except RuntimeError as e: assert "changed size during iteration" in str(e)

print("ok")