From 9f63c4a1456e154e6b48de2f9a8fa5105c8c020b Mon Sep 17 00:00:00 2001
From: Thanos Doukoudakis <thanos.doukoudakis@isode.com>
Date: Wed, 14 Feb 2018 18:00:51 +0000
Subject: Fix a crash that occurs when inviting users in a chat

After inviting people to a chat, and converting to a MUC room, some of the
chat window signals were still signaling the original chat controller,
that has been destroying, causing a crash.

Test-Information:

Tested the changes in Windows 10 (64 bit), after triggering the
dayChangeTimer, and  onContinuationsBroken signal that was causing the
crash.

Change-Id: I70a80ab2653ed87a1dbea851157d95fb5918913f

diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp
index fe8e870..a8ffaf4 100644
--- a/Swift/Controllers/Chat/ChatController.cpp
+++ b/Swift/Controllers/Chat/ChatController.cpp
@@ -86,7 +86,7 @@ ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQ
     chatStateNotifier_->setContactIsOnline(theirPresence && theirPresence->getType() == Presence::Available);
     startMessage += ".";
     chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(startMessage), ChatWindow::DefaultDirection);
-    chatWindow_->onContinuationsBroken.connect([this, startMessage]() { chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(startMessage), ChatWindow::DefaultDirection); });
+    continuationsBrokenConnection_ = chatWindow_->onContinuationsBroken.connect([this, startMessage]() { chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(startMessage), ChatWindow::DefaultDirection); });
     chatWindow_->onUserTyping.connect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_));
     chatWindow_->onUserCancelsTyping.connect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_));
     chatWindow_->onFileTransferStart.connect(boost::bind(&ChatController::handleFileTransferStart, this, _1, _2));
@@ -585,8 +585,20 @@ JID ChatController::messageCorrectionJID(const JID& fromJID) {
 }
 
 ChatWindow* ChatController::detachChatWindow() {
-    chatWindow_->onUserTyping.disconnect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_));
+    continuationsBrokenConnection_.disconnect();
+    chatWindow_->onClosed.disconnect(boost::bind(&ChatController::handleWindowClosed, this));
+    chatWindow_->onInviteToChat.disconnect(boost::bind(&ChatController::handleInviteToChat, this, _1));
+    chatWindow_->onUnblockUserRequest.disconnect(boost::bind(&ChatController::handleUnblockUserRequest, this));
+    chatWindow_->onBlockUserRequest.disconnect(boost::bind(&ChatController::handleBlockUserRequest, this));
+    chatWindow_->onWhiteboardWindowShow.disconnect(boost::bind(&ChatController::handleWhiteboardWindowShow, this));
+    chatWindow_->onWhiteboardSessionCancel.disconnect(boost::bind(&ChatController::handleWhiteboardSessionCancel, this));
+    chatWindow_->onWhiteboardSessionAccept.disconnect(boost::bind(&ChatController::handleWhiteboardSessionAccept, this));
+    chatWindow_->onSendFileRequest.disconnect(boost::bind(&ChatController::handleSendFileRequest, this, _1));
+    chatWindow_->onFileTransferCancel.disconnect(boost::bind(&ChatController::handleFileTransferCancel, this, _1));
+    chatWindow_->onFileTransferAccept.disconnect(boost::bind(&ChatController::handleFileTransferAccept, this, _1, _2));
+    chatWindow_->onFileTransferStart.disconnect(boost::bind(&ChatController::handleFileTransferStart, this, _1, _2));
     chatWindow_->onUserCancelsTyping.disconnect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_));
+    chatWindow_->onUserTyping.disconnect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_));
     return ChatControllerBase::detachChatWindow();
 }
 
diff --git a/Swift/Controllers/Chat/ChatController.h b/Swift/Controllers/Chat/ChatController.h
index d5011e4..a9093d0 100644
--- a/Swift/Controllers/Chat/ChatController.h
+++ b/Swift/Controllers/Chat/ChatController.h
@@ -113,6 +113,7 @@ namespace Swift {
             boost::signals2::scoped_connection blockingOnStateChangedConnection_;
             boost::signals2::scoped_connection blockingOnItemAddedConnection_;
             boost::signals2::scoped_connection blockingOnItemRemovedConnection_;
+            boost::signals2::scoped_connection continuationsBrokenConnection_;
 
             boost::optional<ChatWindow::AlertID> deliveryReceiptAlert_;
             boost::optional<ChatWindow::AlertID> blockedContactAlert_;
diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp
index 0fc735a..19bbf8d 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.cpp
+++ b/Swift/Controllers/Chat/ChatControllerBase.cpp
@@ -58,6 +58,9 @@ void ChatControllerBase::handleContinuationsBroken() {
 }
 
 ChatWindow* ChatControllerBase::detachChatWindow() {
+    chatWindow_->onContinuationsBroken.disconnect(boost::bind(&ChatControllerBase::handleContinuationsBroken, this));
+    chatWindow_->onSendMessageRequest.disconnect(boost::bind(&ChatControllerBase::handleSendMessageRequest, this, _1, _2));
+    chatWindow_->onAllMessagesRead.disconnect(boost::bind(&ChatControllerBase::handleAllMessagesRead, this));
     ChatWindow* chatWindow = chatWindow_;
     chatWindow_ = nullptr;
     return chatWindow;
-- 
cgit v0.10.2-6-g49f6