Use-after-free while pickling dicts · Issue #92930 · python/cpython (original) (raw)
Navigation Menu
- Explore
- Pricing
Provide feedback
Saved searches
Use saved searches to filter your results more quickly
Description
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")