Browse Source

fix(ui): Prevent suicide crash on logout

Fixes #2480

The GUI was deleting itself on logout, but was doing while deep inside the middle of GUI code, resulting in a series of use-after-free on the return path. We now freeze the GUI and logout asynchronously in a more suitable call stack.
pull/3465/merge
tux3 9 years ago
parent
commit
2bdd9824c7
No known key found for this signature in database
GPG Key ID: 7E086DD661263264
  1. 6
      src/nexus.cpp
  2. 6
      src/nexus.h
  3. 4
      src/widget/form/profileform.cpp

6
src/nexus.cpp

@ -258,6 +258,12 @@ bool Nexus::tryRemoveFile(const QString& filepath) @@ -258,6 +258,12 @@ bool Nexus::tryRemoveFile(const QString& filepath)
return writable;
}
void Nexus::showLoginLater()
{
GUI::setEnabled(false);
QMetaObject::invokeMethod(&getInstance(), "showLogin", Qt::QueuedConnection);
}
#ifdef Q_OS_MAC
void Nexus::retranslateUi()
{

6
src/nexus.h

@ -45,7 +45,6 @@ class Nexus : public QObject @@ -45,7 +45,6 @@ class Nexus : public QObject
Q_OBJECT
public:
void start(); ///< Sets up invariants and calls showLogin
void showLogin(); ///< Hides the man GUI, delete the profile, and shows the login screen
/// Hides the login screen and shows the GUI for the given profile.
/// Will delete the current GUI, if it exists.
void showMainGUI();
@ -59,7 +58,12 @@ public: @@ -59,7 +58,12 @@ public:
static QString getSupportedImageFilter();
static bool tryRemoveFile(const QString& filepath); ///< Dangerous way to find out if a path is writable
public slots:
void showLogin(); ///< Hides the man GUI, delete the profile, and shows the login screen
void showLoginLater(); ///< Calls showLogin asynchronously, so we can safely logout from within the main GUI
#ifdef Q_OS_MAC
public:
QMenuBar* globalMenuBar;
QMenu* viewMenu;
QMenu* windowMenu;

4
src/widget/form/profileform.cpp

@ -380,7 +380,7 @@ void ProfileForm::onDeleteClicked() @@ -380,7 +380,7 @@ void ProfileForm::onDeleteClicked()
GUI::showError(tr("Files could not be deleted!", "deletion failed title"), message);
}
nexus.showLogin();
nexus.showLoginLater();
}
}
@ -388,7 +388,7 @@ void ProfileForm::onLogoutClicked() @@ -388,7 +388,7 @@ void ProfileForm::onLogoutClicked()
{
Nexus& nexus = Nexus::getInstance();
Settings::getInstance().saveGlobal();
nexus.showLogin();
nexus.showLoginLater();
}
void ProfileForm::setPasswordButtonsText()

Loading…
Cancel
Save