Fix a use-after-free error during logout

This commit is contained in:
Konstantinos Sideris 2018-08-31 09:10:47 +03:00
parent b10e1bafc8
commit e29fceaee4
6 changed files with 34 additions and 28 deletions

View file

@ -169,24 +169,6 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
}); });
connect(this, &ChatPage::loggedOut, this, &ChatPage::logout); 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::showRoomList, splitter, &Splitter::showFullRoomList);
connect(top_bar_, &TopRoomBar::inviteUsers, this, [this](QStringList users) { connect(top_bar_, &TopRoomBar::inviteUsers, this, [this](QStringList users) {
@ -1332,3 +1314,22 @@ ChatPage::isSideBarExpanded()
{ {
return sideBar_->size().width() > ui::sidebar::NormalSize; 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();
}

View file

@ -72,6 +72,7 @@ public:
void hideSideBars(); void hideSideBars();
//! Show the room/group list (if it was visible). //! Show the room/group list (if it was visible).
void showSideBars(); void showSideBars();
void initiateLogout();
public slots: public slots:
void leaveRoom(const QString &room_id); void leaveRoom(const QString &room_id);

View file

@ -441,15 +441,22 @@ MainWindow::showSolidOverlayModal(QWidget *content, QFlags<Qt::AlignmentFlag> fl
} }
void void
MainWindow::openLogoutDialog(std::function<void()> callback) MainWindow::openLogoutDialog()
{ {
auto dialog = new dialogs::Logout(this); 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_) if (modal_)
modal_->hide(); modal_->hide();
if (logging_out) // By initiating the logout process a new overlay widget
callback(); // 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); showTransparentOverlayModal(dialog, Qt::AlignCenter);

View file

@ -70,7 +70,7 @@ public:
void openCreateRoomDialog( void openCreateRoomDialog(
std::function<void(const mtx::requests::CreateRoom &request)> callback); std::function<void(const mtx::requests::CreateRoom &request)> callback);
void openJoinRoomDialog(std::function<void(const QString &room_id)> 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 openRoomSettings(const QString &room_id = "");
void openMemberListDialog(const QString &room_id = ""); void openMemberListDialog(const QString &room_id = "");
void openUserProfile(const QString &user_id, const QString &room_id); void openUserProfile(const QString &user_id, const QString &room_id);

View file

@ -89,8 +89,8 @@ UserInfoWidget::UserInfoWidget(QWidget *parent)
topLayout_->addLayout(buttonLayout_); topLayout_->addLayout(buttonLayout_);
// Show the confirmation dialog. // Show the confirmation dialog.
connect(logoutButton_, &QPushButton::clicked, this, [this]() { connect(logoutButton_, &QPushButton::clicked, this, []() {
MainWindow::instance()->openLogoutDialog([this]() { emit logout(); }); MainWindow::instance()->openLogoutDialog();
}); });
} }

View file

@ -42,9 +42,6 @@ public:
QColor borderColor() const { return borderColor_; } QColor borderColor() const { return borderColor_; }
void setBorderColor(QColor &color) { borderColor_ = color; } void setBorderColor(QColor &color) { borderColor_ = color; }
signals:
void logout();
protected: protected:
void resizeEvent(QResizeEvent *event) override; void resizeEvent(QResizeEvent *event) override;
void paintEvent(QPaintEvent *event) override; void paintEvent(QPaintEvent *event) override;