S3: Ensure we can copy deleted keys (#5589)

This commit is contained in:
Bert Blommers 2022-10-23 11:23:03 +00:00 committed by GitHub
parent 8c88a93d7c
commit bd465b032b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 1 deletions

View File

@ -305,7 +305,12 @@ class FakeKey(BaseModel, ManagedState):
# https://docs.python.org/3/library/pickle.html#handling-stateful-objects
def __getstate__(self):
state = self.__dict__.copy()
state["value"] = self.value
try:
state["value"] = self.value
except ValueError:
# Buffer is already closed, so we can't reach the data
# Only happens if the key was deleted
state["value"] = ""
del state["_value_buffer"]
del state["lock"]
return state

View File

@ -1,3 +1,4 @@
import copy
import gc
import warnings
from functools import wraps
@ -186,3 +187,21 @@ class TestS3FileHandleClosures(TestCase):
self.s3.delete_object(
bucket_name="my-bucket", key_name="my-key", version_id=key._version_id
)
def test_verify_key_can_be_copied_after_disposing():
# https://github.com/spulec/moto/issues/5588
# Multithreaded bug where:
# - User: calls list_object_versions
# - Moto creates a list of all keys
# - User: deletes a key
# - Moto iterates over the previously created list, that contains a now-deleted key, and creates a copy of it
#
# This test verifies the copy-operation succeeds, it will just not have any data
key = s3model.FakeKey(name="test", bucket_name="bucket", value="sth")
assert not key._value_buffer.closed
key.dispose()
assert key._value_buffer.closed
copied_key = copy.copy(key)
copied_key.value.should.equal(b"")