Repository navigation
Preserve concurrent attachment additions and validate stored text - #548
Merged
Merged
Conversation
…ed input Attachments.add and deletion now read the EmbeddedFiles name tree inside their transaction, so a concurrent addition or deletion is no longer overwritten by a stale snapshot. Attachment.write resolves its stream under the lock, so a concurrent delete cannot leave it writing a stream that another attachment shares. Names, file names, and descriptions are written as the exact str just validated, and data is read through the buffer protocol, so str and bytes subclass overrides cannot bypass the input-size and max_size bounds. Closes #539 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #539
Changes
Attachments.addandAttachments.__delitem__read and plan the/EmbeddedFilesname tree inside their transaction, so add/add, add/delete, and delete/add races no longer write a stale snapshot. Existence and the 4,096-entry bound are checked under the lock as well; a raced duplicate name raisesPdfError, and a raced double delete raisesKeyError.Attachment.writeresolves its file specification and stream under the transaction lock; after a concurrent delete it raisesStaleObjectErrorinstead of editing a stream that another attachment shares, and after a concurrent replacement it writes the new attachment.strwithstr.__str__after validation, so the stored text is the validated text andstrsubclass overrides (__len__,encode,__str__,__eq__) are never called by the writer. The empty-name check usesstr.__len__._validate_datareads data throughmemoryview, which abytessubclass cannot override, checksnbytesagainstmax_size, and writestobytes(). Data that is not bytes-like (for example an int or a list) now raisesTypeError. Before this change,bytes(3)was accepted silently as three zero bytes.Acceptance
strsubclasses or large Unicode input, and serialization uses the validated values (test_str_subclasses_write_their_validated_text,test_large_unicode_text_is_refused_in_utf8_without_changes).Attachments.addandAttachment.writecannot exceedmax_sizethrough a bytes subclass, and write the validated bytes (test_bytes_subclasses_cannot_exceed_max_size,test_bytes_subclasses_write_their_buffer).doc.history.steps. Existing attachment tests andpython3 tools/check.pypass. Current-head CI is pending.All 14 new tests fail on
mainand pass with this change, so each race and bypass was reproduced first.🤖 Generated with Claude Code