Repository navigation
fix(storage): refuse a sub-page file that is not a torn first write (#506, v2.x backport) - #509
Merged
Merged
Conversation
…506) Backport of #508 to v2.x. A file of 1..4095 bytes made FileBackend::open report a new database and write a fresh header over it. It now opens as new only when its bytes are zeros or a prefix of the initial header page; anything else is STG-045 (same number and meaning as on v3), file unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012wXxZguv7PgKQjMMH4yJ5h
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This was referenced Oct 11, 2026
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.
v2.x backport of #508 (merged to
v3). Part of #506, a data-integrity issue that stays open until the fix is in a published release.Problem
FileBackend::opensetis_new = file_len < PAGE_SIZEand wrote a new header over any file under 4 KiB. A database cut below one page by an interrupted copy, or an unrelated file at the path, was silently replaced.Fix
When
0 < file_len < PAGE_SIZE, open reads the bytes and accepts the file as new only if they are zeros or a prefix of the initial header pageopenitself writes (FileHeader::new()padded with zeros). Anything else is refused withSTG-045and the file is left as it was. A zero-length file is still a new database. The code number matches v3 (STG-028–044 exist only on v3, and codes are never reused), so the code means the same thing on both lines.v2.x has no read-only open and no corrupt_file fuzzer, so neither is part of this backport.
Tests
tests/edge_cases_test.rs::test_sub_page_file_refused_unless_torn_first_write: a saved database cut to 2,222 and 20 bytes, and foreign bytes, each giveSTG-045, with the file unchanged and no WAL created. 4- and 10-byte header prefixes and 300 zeros open, take a write, and read it back after reopen. The test fails without the fix ("opened" instead of STG-045).cargo test: 1,216 passed, 8 ignored.cargo clippy --all-features -- -D warningsis clean.Docs:
ERROR_REFERENCE.md(STG-045),CHANGELOG.md(Unreleased),TEST_COVERAGE.md, and the test counts inCLAUDE.mdandREADME.md.🤖 Generated with Claude Code
https://claude.ai/code/session_012wXxZguv7PgKQjMMH4yJ5h