Repository navigation
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Two active issues remain in src/core/Database.cpp: an unbalanced Windows error message and a source-text change that would invalidate existing translations.
2 open issues
What changed in this PR
This pull request reworks KeePassXC’s TempFile database-saving path to stage data in a sibling file, synchronize it, and perform platform-native replacement, improving reliability on remote filesystems.
Changes:
- Added POSIX and Windows file synchronization and replacement helpers.
- Reworked staged saves to preserve the original database on replacement failures and retain recovery copies.
- Updated save-method documentation and removed the obsolete restore helper.
- Added regression coverage for staged saves, atomic saves, permissions, recovery, failures, and cleanup.
Review comments remain regarding an unbalanced Windows error message, translation-string compatibility, long filenames exceeding filesystem limits, and replacement of dangling Windows symlinks.
| File | Description |
|---|---|
tests/TestDatabase.h |
Declares the new staged-save test cases. |
tests/TestDatabase.cpp |
Adds coverage for staged saves, atomic saves, failure preservation, recovery, permissions, and temporary-file cleanup. |
src/core/Database.h |
Updates save-method documentation and removes the obsolete restore helper declaration. |
src/core/Database.cpp |
Implements file synchronization, native replacement, staged sibling writes, recovery handling, and related save-path logic. |
Review effort: Lite
8ec9e7f to
97d19fc
Compare
68dc292 to
1765b06
Compare
There was a problem hiding this comment.
🟡 Changes recommended
A critical test assertion omits “database” from the expected backup-path pattern, so the staged-save recovery check fails at regex matching instead of validating recovery.
1 open issue
2 resolved since last review
Review effort: Lite
1765b06 to
6482ea5
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #13992 +/- ##
===========================================
+ Coverage 61.19% 61.24% +0.05%
===========================================
Files 396 396
Lines 37926 37988 +62
===========================================
+ Hits 23208 23264 +56
- Misses 14718 14724 +6 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Fixes #13970 The previous TempFile saving method failed under Qt6 on certain remote file systems that don't support hard-linking or O_TMPFILE renames, such as remote SMB shares. Here, QFile::rename() created an unamed Q_TMPFILE, and tried to rename it with linkat(), which failed. Since QFile::rename() does not do file replacements, KeePassXC had to remove the target before moving the new file in place, which could cause to data loss when the rename failed. This patch changes TempFile to a hybrid approach: The database is first written to a temporary file. The temporary file is committed to disk, and then streamed to a named sibling of the target file. Streaming avoids using QFile::copy() or QFile::rename(), which can trigger the failure. After straming the file back, the target file is replaced atomically (if possible) with the sibling.
e74c406 to
b92e84c
Compare
b92e84c to
45056dc
Compare


Fixes #13970
The previous TempFile saving method failed under Qt6 on certain remote file systems that don't support hard-linking or O_TMPFILE renames, such as remote SMB shares. Here, QFile::rename() created an unamed Q_TMPFILE, and tried to rename it with linkat(), which failed. Since QFile::rename() does not do file replacements, KeePassXC had to remove the target before moving the new file in place, which could cause to data loss when the rename failed.
This patch changes TempFile to a hybrid approach: The database is first written to a temporary file. The temporary file is committed to disk, and then streamed to a named sibling of the target file. Streaming avoids using QFile::copy() or QFile::rename(), which can trigger the failure. After straming the file back, the target file is replaced atomically (if possible) with the sibling.
Warning
Needs testing. It's quite possible that it fixes the addressed issue, but reintroduces the Dropbox locking issues that the original TempFile saving method was supposed to solve.
Codex created a first rough draft and wrote the tests.
Type of change