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!
This commit is contained in:
Jonathan White 2025-03-06 22:41:09 -05:00
parent 33a3796074
commit e8dffe7a8f
No known key found for this signature in database
GPG Key ID: 440FC65F2E0C6E01

View File

@ -434,16 +434,23 @@ bool Database::performSave(const QString& filePath, SaveAction action, const QSt
break; break;
} }
case DirectWrite: { 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 // Open the original database file for direct-write
QFile dbFile(filePath); QFile dbFile(filePath);
if (dbFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { if (dbFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
HashingStream hashingStream(&dbFile, QCryptographicHash::Md5, kFileBlockToHashSizeBytes); dbFile.write(dbBuffer.data());
if (!hashingStream.open(QIODevice::WriteOnly)) {
return false;
}
if (!writeDatabase(&hashingStream, error)) {
return false;
}
dbFile.close(); dbFile.close();
// store the new hash // store the new hash
m_fileBlockHash = hashingStream.hashingResult(); m_fileBlockHash = hashingStream.hashingResult();