Fix saving database backup file

* Fixes #11831
* Also fixes weird issues like saving backup of a backup due to function reuse
This commit is contained in:
Jonathan White 2025-03-10 20:31:18 -04:00
parent 33a3796074
commit 418397fb28
No known key found for this signature in database
GPG Key ID: 440FC65F2E0C6E01
2 changed files with 39 additions and 35 deletions

View File

@ -2825,6 +2825,10 @@ Disable safe saves and try again?</source>
<source>Database file on disk cannot be unlocked with current credentials.&lt;br&gt;Enter new credentials and/or present hardware key to continue.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to save backup database: %1</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditEntryWidget</name>

View File

@ -2615,12 +2615,11 @@ bool DatabaseWidget::performSave(QString& errorMessage, const QString& fileName)
*/
bool DatabaseWidget::saveBackup()
{
while (true) {
QString oldFilePath = m_db->filePath();
if (!QFileInfo::exists(oldFilePath)) {
QString defaultFileName = config()->get(Config::DefaultDatabaseFileName).toString();
oldFilePath = QDir::toNativeSeparators(
FileDialog::getLastDir("db") + "/"
oldFilePath =
QDir::toNativeSeparators(FileDialog::getLastDir("db") + "/"
+ (defaultFileName.isEmpty() ? tr("Passwords").append(".kdbx") : defaultFileName));
}
@ -2629,31 +2628,32 @@ bool DatabaseWidget::saveBackup()
FileDialog::getLastDir("backup", oldFilePath),
tr("KeePass 2 Database").append(" (*.kdbx)"));
if (!newFilePath.isEmpty()) {
// Ensure we don't recurse back into this function
m_db->setFilePath(newFilePath);
m_saveAttempts = 0;
bool modified = m_db->isModified();
if (!save()) {
// Failed to save, try again
m_db->setFilePath(oldFilePath);
continue;
// Early out if we canceled the file selection
if (newFilePath.isEmpty()) {
return false;
}
// Record modified state so we can restore after save
bool modified = m_db->isModified();
QString error;
bool ok = m_db->saveAs(newFilePath, Database::DirectWrite, {}, &error);
// Restore database to original state
m_db->setFilePath(oldFilePath);
if (modified) {
// Source database is marked as clean when copy is saved, even if source has unsaved changes
m_db->markAsModified();
}
FileDialog::saveLastDir("backup", newFilePath, true);
return true;
}
// Canceled file selection
if (!ok) {
// Failed to save backup, post the error
showErrorMessage(tr("Failed to save backup database: %1").arg(error));
return false;
}
FileDialog::saveLastDir("backup", newFilePath, true);
return true;
}
void DatabaseWidget::showMessage(const QString& text,