Fix logout current connection crash

Make sure that the neochat can handle switching connection when the current one is logged out. This is mostly about using QPointer to handle use after free issues due to room objects being deleted.
This commit is contained in:
James Graham
2024-03-27 15:25:24 +00:00
parent 0ab8624d79
commit 0f9eb4beeb
7 changed files with 18 additions and 13 deletions

View File

@@ -156,6 +156,15 @@ void Controller::addConnection(NeoChatConnection *c)
c->saveState(); c->saveState();
}); });
connect(c, &NeoChatConnection::loggedOut, this, [this, c] { connect(c, &NeoChatConnection::loggedOut, this, [this, c] {
if (accounts().count() > 1) {
// Only set the connection if the the account being logged out is currently active
if (c == activeConnection()) {
setActiveConnection(dynamic_cast<NeoChatConnection *>(accounts().accounts()[0]));
}
} else {
setActiveConnection(nullptr);
}
dropConnection(c); dropConnection(c);
}); });
connect(c, &NeoChatConnection::badgeNotificationCountChanged, this, &Controller::updateBadgeNotificationCount); connect(c, &NeoChatConnection::badgeNotificationCountChanged, this, &Controller::updateBadgeNotificationCount);

View File

@@ -629,6 +629,10 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
int MessageEventModel::eventIdToRow(const QString &eventID) const int MessageEventModel::eventIdToRow(const QString &eventID) const
{ {
if (m_currentRoom == nullptr) {
return -1;
}
const auto it = m_currentRoom->findInTimeline(eventID); const auto it = m_currentRoom->findInTimeline(eventID);
if (it == m_currentRoom->historyEdge()) { if (it == m_currentRoom->historyEdge()) {
// qWarning() << "Trying to find inexistent event:" << eventID; // qWarning() << "Trying to find inexistent event:" << eventID;

View File

@@ -113,7 +113,7 @@ private Q_SLOTS:
void refreshRow(int row); void refreshRow(int row);
private: private:
NeoChatRoom *m_currentRoom = nullptr; QPointer<NeoChatRoom> m_currentRoom = nullptr;
QString lastReadEventId; QString lastReadEventId;
QPersistentModelIndex m_lastReadEventIndex; QPersistentModelIndex m_lastReadEventIndex;
int rowBelowInserted = -1; int rowBelowInserted = -1;

View File

@@ -61,7 +61,7 @@ public:
[[nodiscard]] QHash<int, QByteArray> roleNames() const override; [[nodiscard]] QHash<int, QByteArray> roleNames() const override;
private: private:
NeoChatRoom *m_room = nullptr; QPointer<NeoChatRoom> m_room = nullptr;
}; };
/** /**

View File

@@ -153,14 +153,6 @@ void NeoChatConnection::logout(bool serverSideLogout)
job.start(); job.start();
loop.exec(); loop.exec();
if (Controller::instance().accounts().count() > 1) {
// Only set the connection if the the account being logged out is currently active
if (this == Controller::instance().activeConnection()) {
Controller::instance().setActiveConnection(dynamic_cast<NeoChatConnection *>(Controller::instance().accounts().accounts()[0]));
}
} else {
Controller::instance().setActiveConnection(nullptr);
}
if (!serverSideLogout) { if (!serverSideLogout) {
return; return;
} }

View File

@@ -57,7 +57,7 @@ void NotificationsManager::processNotificationJob(QPointer<NeoChatConnection> co
if (job == nullptr) { if (job == nullptr) {
return; return;
} }
if (connection == nullptr) { if (connection == nullptr || !connection->isLoggedIn()) {
qWarning() << QStringLiteral("No connection for GetNotificationsJob %1").arg(job->objectName()); qWarning() << QStringLiteral("No connection for GetNotificationsJob %1").arg(job->objectName());
return; return;
} }
@@ -150,7 +150,7 @@ void NotificationsManager::processNotificationJob(QPointer<NeoChatConnection> co
bool NotificationsManager::shouldPostNotification(QPointer<NeoChatConnection> connection, const QJsonValue &notification) bool NotificationsManager::shouldPostNotification(QPointer<NeoChatConnection> connection, const QJsonValue &notification)
{ {
if (connection == nullptr) { if (connection == nullptr || !connection->isLoggedIn()) {
return false; return false;
} }

View File

@@ -340,7 +340,7 @@ Q_SIGNALS:
private: private:
void openRoomForActiveConnection(); void openRoomForActiveConnection();
NeoChatRoom *m_currentRoom; QPointer<NeoChatRoom> m_currentRoom;
NeoChatRoom *m_lastCurrentRoom; NeoChatRoom *m_lastCurrentRoom;
QString m_arg; QString m_arg;
KSharedConfig::Ptr m_config; KSharedConfig::Ptr m_config;