Skip to content

Fix atomic file writes exposing empty destinations and leaking temp files - #9805

Merged
hsbt merged 2 commits into
masterfrom
atomic-file-writer-flush-cleanup
Aug 25, 2026
Merged

Fix atomic file writes exposing empty destinations and leaking temp files#9805
hsbt merged 2 commits into
masterfrom
atomic-file-writer-flush-cleanup

Conversation

@hsbt

@hsbt hsbt commented Aug 24, 2026

Copy link
Copy Markdown
Member

Gem::AtomicFileWriter renamed the temporary file into place before closing it, so buffered data had not reached the filesystem yet. A concurrent reader could observe an empty destination, and a flush failure such as ENOSPC would surface only after the destination had already been replaced with a truncated file. Closing before the rename restores the ordering the writer had before it was refactored.

The cleanup path had also become rescue StandardError, so an Interrupt from Ctrl-C skipped both the unlink and the rename and left .<name>.tmp.<hex> behind. It is back in an ensure block.

Basename truncation used byteslice, which can cut a multibyte character in half and make the temporary file name fail with EILSEQ on filesystems that enforce UTF-8 validity such as APFS. It now trims at a character boundary.

This file had a single test before. The invariants above are covered now.

Comment thread test/rubygems/test_gem_util_atomic_file_writer.rb Fixed
hsbt and others added 2 commits August 25, 2026 11:04
The basename was cut with byteslice, which can split a multibyte
character in half. Filesystems enforcing UTF-8 validity such as APFS then
reject the temporary name with EILSEQ.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The temporary file was renamed into place before being closed, so
buffered data had not reached the filesystem yet and a concurrent reader
could observe an empty destination. A flush failure such as ENOSPC would
surface only after the destination had already been replaced. Cleanup
also moved to an ensure block, so an interrupt no longer leaks the
temporary file.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@hsbt
hsbt force-pushed the atomic-file-writer-flush-cleanup branch from eecd199 to 774bd08 Compare August 25, 2026 02:04
@hsbt
hsbt merged commit b3f354a into master Aug 25, 2026
107 checks passed
@hsbt
hsbt deleted the atomic-file-writer-flush-cleanup branch August 25, 2026 03:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant