mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-12-28 08:49:42 -05:00
Prevent crash when KeeShare merges an entry that is in edit mode
* Hack for #5722 until a refactor of KeeShare, Merger, and EditEntryWidget can be performed. This hack should only ever be triggered on the rare occurrence of two people editing the same entry at the same time. The end result is potential data loss, but the current result is a hard crash. Unfortunately the way everything is interfaced currently doesn't afford any solution without a major refactor. * Additionally add a short delay before actually reloading a share to prevent read/write locks from preventing proper import. This delay also prevents conflicting saves between the main database and the KeeShare database. This should eventually be moved into the FileObserver itself to smooth out all merge operations once the above refactor occurs. Side note: KeeShare operates independently of DatabaseWidget causing unexpected behavior when files are updated/merged/etc. This needs to be corrected in a refactor.
This commit is contained in:
parent
f9b2cf8484
commit
60c2d89cb0
@ -994,6 +994,15 @@ bool EditEntryWidget::commitEntry()
|
||||
return true;
|
||||
}
|
||||
|
||||
// HACK: Check that entry pointer is still valid, see https://github.com/keepassxreboot/keepassxc/issues/5722
|
||||
if (!m_entry) {
|
||||
QMessageBox::information(this,
|
||||
tr("Invalid Entry"),
|
||||
tr("An external merge operation has invalidated this entry.\n"
|
||||
"Unfortunately, any changes made have been lost."));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check Auto-Type validity early
|
||||
if (!AutoType::verifyAutoTypeSyntax(m_autoTypeUi->sequenceEdit->text())) {
|
||||
return false;
|
||||
|
@ -186,23 +186,29 @@ void ShareObserver::handleDatabaseChanged()
|
||||
|
||||
void ShareObserver::handleFileUpdated(const QString& path)
|
||||
{
|
||||
const Result result = importShare(path);
|
||||
if (!result.isValid()) {
|
||||
return;
|
||||
if (!m_inFileUpdate) {
|
||||
QTimer::singleShot(100, this, [this, path] {
|
||||
const Result result = importShare(path);
|
||||
m_inFileUpdate = false;
|
||||
if (!result.isValid()) {
|
||||
return;
|
||||
}
|
||||
QStringList success;
|
||||
QStringList warning;
|
||||
QStringList error;
|
||||
if (result.isError()) {
|
||||
error << tr("Import from %1 failed (%2)").arg(result.path, result.message);
|
||||
} else if (result.isWarning()) {
|
||||
warning << tr("Import from %1 failed (%2)").arg(result.path, result.message);
|
||||
} else if (result.isInfo()) {
|
||||
success << tr("Import from %1 successful (%2)").arg(result.path, result.message);
|
||||
} else {
|
||||
success << tr("Imported from %1").arg(result.path);
|
||||
}
|
||||
notifyAbout(success, warning, error);
|
||||
});
|
||||
m_inFileUpdate = true;
|
||||
}
|
||||
QStringList success;
|
||||
QStringList warning;
|
||||
QStringList error;
|
||||
if (result.isError()) {
|
||||
error << tr("Import from %1 failed (%2)").arg(result.path, result.message);
|
||||
} else if (result.isWarning()) {
|
||||
warning << tr("Import from %1 failed (%2)").arg(result.path, result.message);
|
||||
} else if (result.isInfo()) {
|
||||
success << tr("Import from %1 successful (%2)").arg(result.path, result.message);
|
||||
} else {
|
||||
success << tr("Imported from %1").arg(result.path);
|
||||
}
|
||||
notifyAbout(success, warning, error);
|
||||
}
|
||||
|
||||
ShareObserver::Result ShareObserver::importShare(const QString& path)
|
||||
|
@ -83,6 +83,7 @@ private:
|
||||
QMap<QPointer<Group>, KeeShareSettings::Reference> m_groupToReference;
|
||||
QMap<QString, QPointer<Group>> m_shareToGroup;
|
||||
QMap<QString, QSharedPointer<FileWatcher>> m_fileWatchers;
|
||||
bool m_inFileUpdate = false;
|
||||
};
|
||||
|
||||
#endif // KEEPASSXC_SHAREOBSERVER_H
|
||||
|
Loading…
Reference in New Issue
Block a user