Skip to content

Use-after-free while pickling dicts #92930

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.

importpicklefromrandomimportgetrandbitsclassBad:
def__eq__(self, other):
ifnotENABLED:
returnFalsebreak_things()
returngetrandbits(4) ==0def__hash__(self):
returngetrandbits(1)
def__reduce__(self):
break_things()
return (Bad, (), ())
def__setstate__(self, *args):
break_things()
def__del__(self):
break_things()
def__getattr__(self):
break_things()
defbreak_things():
ifgetrandbits(6) ==0:
collection.clear()
TRIALS=10_000SIZE=50foriinrange(TRIALS):
try:
ENABLED=Falsecollection= {Bad():Bad() for_inrange(SIZE)}
forbadincollection:
bad.bad=badbad.collection=collectionENABLED=Truepickle.loads(pickle.dumps(collection))
exceptRuntimeErrorase:
assert"changed size during iteration"instr(e)
print("ok")

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-crashA hard crash of the interpreter, possibly with a core dump

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions