From e8dffe7a8f7bfbcfea29ae30c6b5328a5ad3d542 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Thu, 6 Mar 2025 22:41:09 -0500 Subject: [PATCH] Write to buffer before writing directly to database file * Fixes #11819 When direct write save option is enabled and a hardware key is used with a press required, it is possible that the database file will be truncated to 0 bytes. This is avoided by writing the database to a memory buffer first allowing for key transform to occur, then dumping the buffer into the database file. This change also improves the overall safety of the direct write save option as there is far less chance for an error to occur while writing to the database file. Thanks to @ChrisLnrn for reporting this issue! --- src/core/Database.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/core/Database.cpp b/src/core/Database.cpp index b25183118..3b499e8e6 100644 --- a/src/core/Database.cpp +++ b/src/core/Database.cpp @@ -434,16 +434,23 @@ bool Database::performSave(const QString& filePath, SaveAction action, const QSt break; } case DirectWrite: { + QBuffer dbBuffer; + dbBuffer.open(QIODevice::WriteOnly); + HashingStream hashingStream(&dbBuffer, QCryptographicHash::Md5, kFileBlockToHashSizeBytes); + if (!hashingStream.open(QIODevice::WriteOnly)) { + if (error) { + *error = hashingStream.errorString(); + } + return false; + } + if (!writeDatabase(&hashingStream, error)) { + return false; + } + // Open the original database file for direct-write QFile dbFile(filePath); if (dbFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { - HashingStream hashingStream(&dbFile, QCryptographicHash::Md5, kFileBlockToHashSizeBytes); - if (!hashingStream.open(QIODevice::WriteOnly)) { - return false; - } - if (!writeDatabase(&hashingStream, error)) { - return false; - } + dbFile.write(dbBuffer.data()); dbFile.close(); // store the new hash m_fileBlockHash = hashingStream.hashingResult();