summary refs log tree commit diff
diff options
context:
space:
mode:
authorKonstantinos Sideris <sideris.konstantin@gmail.com>2018-08-31 09:10:47 +0300
committerKonstantinos Sideris <sideris.konstantin@gmail.com>2018-08-31 09:10:47 +0300
commite29fceaee47e0a2edba83605c7fa2789cfb8de1e (patch)
treed25d031444c9cac5859dadba805c93d6953fa68e
parentAdd temp fix to work with servers that don't support e2ee endpoints (diff)
downloadnheko-e29fceaee47e0a2edba83605c7fa2789cfb8de1e.tar.xz
Fix a use-after-free error during logout
-rw-r--r--src/ChatPage.cpp37
-rw-r--r--src/ChatPage.h1
-rw-r--r--src/MainWindow.cpp15
-rw-r--r--src/MainWindow.h2
-rw-r--r--src/UserInfoWidget.cpp4
-rw-r--r--src/UserInfoWidget.h3
6 files changed, 34 insertions, 28 deletions
diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index b7cb999f..4bb7b497 100644
--- a/src/ChatPage.cpp
+++ b/src/ChatPage.cpp
@@ -169,24 +169,6 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
         });
 
         connect(this, &ChatPage::loggedOut, this, &ChatPage::logout);
-        connect(user_info_widget_, &UserInfoWidget::logout, this, [this]() {
-                http::client()->logout(
-                  [this](const mtx::responses::Logout &, mtx::http::RequestErr err) {
-                          if (err) {
-                                  // TODO: handle special errors
-                                  emit contentLoaded();
-                                  nhlog::net()->warn(
-                                    "failed to logout: {} - {}",
-                                    mtx::errors::to_string(err->matrix_error.errcode),
-                                    err->matrix_error.error);
-                                  return;
-                          }
-
-                          emit loggedOut();
-                  });
-
-                emit showOverlayProgressBar();
-        });
 
         connect(top_bar_, &TopRoomBar::showRoomList, splitter, &Splitter::showFullRoomList);
         connect(top_bar_, &TopRoomBar::inviteUsers, this, [this](QStringList users) {
@@ -1332,3 +1314,22 @@ ChatPage::isSideBarExpanded()
 {
         return sideBar_->size().width() > ui::sidebar::NormalSize;
 }
+
+void
+ChatPage::initiateLogout()
+{
+        http::client()->logout([this](const mtx::responses::Logout &, mtx::http::RequestErr err) {
+                if (err) {
+                        // TODO: handle special errors
+                        emit contentLoaded();
+                        nhlog::net()->warn("failed to logout: {} - {}",
+                                           mtx::errors::to_string(err->matrix_error.errcode),
+                                           err->matrix_error.error);
+                        return;
+                }
+
+                emit loggedOut();
+        });
+
+        emit showOverlayProgressBar();
+}
diff --git a/src/ChatPage.h b/src/ChatPage.h
index 5bb7ecae..9398b443 100644
--- a/src/ChatPage.h
+++ b/src/ChatPage.h
@@ -72,6 +72,7 @@ public:
         void hideSideBars();
         //! Show the room/group list (if it was visible).
         void showSideBars();
+        void initiateLogout();
 
 public slots:
         void leaveRoom(const QString &room_id);
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index a93f0c9f..95c56554 100644
--- a/src/MainWindow.cpp
+++ b/src/MainWindow.cpp
@@ -441,15 +441,22 @@ MainWindow::showSolidOverlayModal(QWidget *content, QFlags<Qt::AlignmentFlag> fl
 }
 
 void
-MainWindow::openLogoutDialog(std::function<void()> callback)
+MainWindow::openLogoutDialog()
 {
         auto dialog = new dialogs::Logout(this);
-        connect(dialog, &dialogs::Logout::closing, this, [this, callback](bool logging_out) {
+        connect(dialog, &dialogs::Logout::closing, this, [this](bool logging_out) {
                 if (modal_)
                         modal_->hide();
 
-                if (logging_out)
-                        callback();
+                // By initiating the logout process a new overlay widget
+                // will replace & destroy the previous widget (logout dialog).
+                //
+                // This will force the destruction of the logout widget to
+                // happen after the click event has been fully processed.
+                QTimer::singleShot(0, this, [logging_out, this]() {
+                        if (logging_out)
+                                chat_page_->initiateLogout();
+                });
         });
 
         showTransparentOverlayModal(dialog, Qt::AlignCenter);
diff --git a/src/MainWindow.h b/src/MainWindow.h
index 0fa49f17..1953ba0e 100644
--- a/src/MainWindow.h
+++ b/src/MainWindow.h
@@ -70,7 +70,7 @@ public:
         void openCreateRoomDialog(
           std::function<void(const mtx::requests::CreateRoom &request)> callback);
         void openJoinRoomDialog(std::function<void(const QString &room_id)> callback);
-        void openLogoutDialog(std::function<void()> callback);
+        void openLogoutDialog();
         void openRoomSettings(const QString &room_id = "");
         void openMemberListDialog(const QString &room_id = "");
         void openUserProfile(const QString &user_id, const QString &room_id);
diff --git a/src/UserInfoWidget.cpp b/src/UserInfoWidget.cpp
index c0409823..c3f541ba 100644
--- a/src/UserInfoWidget.cpp
+++ b/src/UserInfoWidget.cpp
@@ -89,8 +89,8 @@ UserInfoWidget::UserInfoWidget(QWidget *parent)
         topLayout_->addLayout(buttonLayout_);
 
         // Show the confirmation dialog.
-        connect(logoutButton_, &QPushButton::clicked, this, [this]() {
-                MainWindow::instance()->openLogoutDialog([this]() { emit logout(); });
+        connect(logoutButton_, &QPushButton::clicked, this, []() {
+                MainWindow::instance()->openLogoutDialog();
         });
 }
 
diff --git a/src/UserInfoWidget.h b/src/UserInfoWidget.h
index ea2d5400..65de7be9 100644
--- a/src/UserInfoWidget.h
+++ b/src/UserInfoWidget.h
@@ -42,9 +42,6 @@ public:
         QColor borderColor() const { return borderColor_; }
         void setBorderColor(QColor &color) { borderColor_ = color; }
 
-signals:
-        void logout();
-
 protected:
         void resizeEvent(QResizeEvent *event) override;
         void paintEvent(QPaintEvent *event) override;