From f149101d255d1aa466bf7a6497e19b6439811c1d Mon Sep 17 00:00:00 2001 From: Nick Bolton Date: Thu, 6 Feb 2014 18:39:12 +0000 Subject: [PATCH] fixed: linux client crashes on file drop, even though drag and drop is disabled --- src/lib/client/CClient.cpp | 42 +++++++++++++++----------- src/lib/client/CClient.h | 4 ++- src/lib/platform/CMSWindowsScreen.cpp | 6 ---- src/lib/platform/CMSWindowsScreen.h | 1 - src/lib/platform/COSXScreen.cpp | 10 +++---- src/lib/server/CServer.cpp | 43 ++++++++++++++++----------- src/lib/server/CServer.h | 3 +- src/lib/synergy/CClientApp.cpp | 3 +- src/lib/synergy/CPlatformScreen.h | 4 +-- src/lib/synergy/CServerApp.cpp | 2 +- src/test/integtests/NetworkTests.cpp | 16 +++++----- 11 files changed, 72 insertions(+), 62 deletions(-) diff --git a/src/lib/client/CClient.cpp b/src/lib/client/CClient.cpp index bf8f3c16..9d85c95d 100644 --- a/src/lib/client/CClient.cpp +++ b/src/lib/client/CClient.cpp @@ -51,7 +51,8 @@ CClient::CClient(IEventQueue* events, ISocketFactory* socketFactory, IStreamFilterFactory* streamFilterFactory, CScreen* screen, - const CCryptoOptions& crypto) : + const CCryptoOptions& crypto, + bool enableDragDrop) : m_mock(false), m_name(name), m_serverAddress(address), @@ -69,7 +70,8 @@ CClient::CClient(IEventQueue* events, m_cryptoStream(NULL), m_crypto(crypto), m_sendFileThread(NULL), - m_writeToDropDirThread(NULL) + m_writeToDropDirThread(NULL), + m_enableDragDrop(false) { assert(m_socketFactory != NULL); assert(m_screen != NULL); @@ -83,14 +85,17 @@ CClient::CClient(IEventQueue* events, getEventTarget(), new TMethodEventJob(this, &CClient::handleResume)); - m_events->adoptHandler(m_events->forIScreen().fileChunkSending(), - this, - new TMethodEventJob(this, - &CClient::handleFileChunkSending)); - m_events->adoptHandler(m_events->forIScreen().fileRecieveCompleted(), - this, - new TMethodEventJob(this, - &CClient::handleFileRecieveCompleted)); + + if (m_enableDragDrop) { + m_events->adoptHandler(m_events->forIScreen().fileChunkSending(), + this, + new TMethodEventJob(this, + &CClient::handleFileChunkSending)); + m_events->adoptHandler(m_events->forIScreen().fileRecieveCompleted(), + this, + new TMethodEventJob(this, + &CClient::handleFileRecieveCompleted)); + } } CClient::~CClient() @@ -110,7 +115,6 @@ CClient::~CClient() cleanupConnection(); delete m_socketFactory; delete m_streamFilterFactory; - delete m_sendFileThread; } void @@ -782,12 +786,17 @@ CClient::fileChunkReceived(CString data) void CClient::dragInfoReceived(UInt32 fileNum, CString data) { - LOG((CLOG_DEBUG "drag information received")); - LOG((CLOG_DEBUG "parsing drag info data: %s", data.c_str())); - CDragInformation::parseDragInfo(m_dragFileList, fileNum, data); - LOG((CLOG_DEBUG "total drag file number: %i", m_dragFileList.size())); + // TODO: fix duplicate function from CServer - for(int i = 0; i < m_dragFileList.size(); ++i) { + if (!m_enableDragDrop) { + LOG((CLOG_DEBUG "drag drop not enabled, ignoring drag info.")); + return; + } + + CDragInformation::parseDragInfo(m_dragFileList, fileNum, data); + LOG((CLOG_DEBUG "drag info received, total drag file number: %i", m_dragFileList.size())); + + for (int i = 0; i < m_dragFileList.size(); ++i) { LOG((CLOG_DEBUG2 "dragging file %i name: %s", i + 1, m_dragFileList.at(i).c_str())); } @@ -830,7 +839,6 @@ CClient::sendFileThread(void* filename) LOG((CLOG_ERR "failed sending file chunks: %s", error.what())); } - delete m_sendFileThread; m_sendFileThread = NULL; } diff --git a/src/lib/client/CClient.h b/src/lib/client/CClient.h index 5b746714..50bfcd16 100644 --- a/src/lib/client/CClient.h +++ b/src/lib/client/CClient.h @@ -62,7 +62,8 @@ public: ISocketFactory* socketFactory, IStreamFilterFactory* streamFilterFactory, CScreen* screen, - const CCryptoOptions& crypto); + const CCryptoOptions& crypto, + bool enableDragDrop); ~CClient(); #ifdef TEST_ENV @@ -236,6 +237,7 @@ private: CString m_dragFileExt; CThread* m_sendFileThread; CThread* m_writeToDropDirThread; + bool m_enableDragDrop; }; #endif diff --git a/src/lib/platform/CMSWindowsScreen.cpp b/src/lib/platform/CMSWindowsScreen.cpp index 7efe6c32..1d1c3585 100644 --- a/src/lib/platform/CMSWindowsScreen.cpp +++ b/src/lib/platform/CMSWindowsScreen.cpp @@ -1888,12 +1888,6 @@ CMSWindowsScreen::CHotKeyItem::operator<(const CHotKeyItem& x) const (m_keycode == x.m_keycode && m_mask < x.m_mask)); } -void -CMSWindowsScreen::fakeDraggingFiles(CString str) -{ - -} - CString& CMSWindowsScreen::getDraggingFileDir() { diff --git a/src/lib/platform/CMSWindowsScreen.h b/src/lib/platform/CMSWindowsScreen.h index ed7957e1..84b0c314 100644 --- a/src/lib/platform/CMSWindowsScreen.h +++ b/src/lib/platform/CMSWindowsScreen.h @@ -115,7 +115,6 @@ public: virtual void setOptions(const COptionsList& options); virtual void setSequenceNumber(UInt32); virtual bool isPrimary() const; - virtual void fakeDraggingFiles(CString str); virtual CString& getDraggingFileDir(); virtual const CString& getDropTarget() const; diff --git a/src/lib/platform/COSXScreen.cpp b/src/lib/platform/COSXScreen.cpp index 6fddce96..234bf304 100644 --- a/src/lib/platform/COSXScreen.cpp +++ b/src/lib/platform/COSXScreen.cpp @@ -2095,15 +2095,13 @@ COSXScreen::CFStringRefToUTF8String(CFStringRef aString) void COSXScreen::fakeDraggingFiles(CString str) { - if (CApp::instance().argsBase().m_enableDragDrop) { - m_fakeDraggingStarted = true; + m_fakeDraggingStarted = true; #if defined(MAC_OS_X_VERSION_10_7) - // TODO: use real file extension - fakeDragging("txt", 3, m_xCursor, m_yCursor); + // TODO: use real file extension + fakeDragging("txt", 3, m_xCursor, m_yCursor); #else - LOG((CLOG_WARN "drag drop not supported")); + LOG((CLOG_WARN "drag drop not supported")); #endif - } } CString& diff --git a/src/lib/server/CServer.cpp b/src/lib/server/CServer.cpp index a1fed577..0d7ea807 100644 --- a/src/lib/server/CServer.cpp +++ b/src/lib/server/CServer.cpp @@ -47,7 +47,7 @@ // CServer // -CServer::CServer(CConfig& config, CPrimaryClient* primaryClient, CScreen* screen, IEventQueue* events) : +CServer::CServer(CConfig& config, CPrimaryClient* primaryClient, CScreen* screen, IEventQueue* events, bool enableDragDrop) : m_events(events), m_mock(false), m_primaryClient(primaryClient), @@ -77,7 +77,8 @@ CServer::CServer(CConfig& config, CPrimaryClient* primaryClient, CScreen* screen m_screen(screen), m_sendFileThread(NULL), m_writeToDropDirThread(NULL), - m_ignoreFileTransfer(false) + m_ignoreFileTransfer(false), + m_enableDragDrop(enableDragDrop) { // must have a primary client and it must have a canonical name assert(m_primaryClient != NULL); @@ -166,14 +167,17 @@ CServer::CServer(CConfig& config, CPrimaryClient* primaryClient, CScreen* screen m_inputFilter, new TMethodEventJob(this, &CServer::handleFakeInputEndEvent)); - m_events->adoptHandler(m_events->forIScreen().fileChunkSending(), - this, - new TMethodEventJob(this, - &CServer::handleFileChunkSendingEvent)); - m_events->adoptHandler(m_events->forIScreen().fileRecieveCompleted(), - this, - new TMethodEventJob(this, - &CServer::handleFileRecieveCompletedEvent)); + + if (m_enableDragDrop) { + m_events->adoptHandler(m_events->forIScreen().fileChunkSending(), + this, + new TMethodEventJob(this, + &CServer::handleFileChunkSendingEvent)); + m_events->adoptHandler(m_events->forIScreen().fileRecieveCompleted(), + this, + new TMethodEventJob(this, + &CServer::handleFileRecieveCompletedEvent)); + } // add connection addClient(m_primaryClient); @@ -245,8 +249,6 @@ CServer::~CServer() // disable and disconnect primary client m_primaryClient->disable(); removeClient(m_primaryClient); - - delete m_sendFileThread; } bool @@ -1666,7 +1668,7 @@ CServer::onMouseUp(ButtonID id) return; } - if (!m_screen->isOnScreen()) { + if (m_enableDragDrop && !m_screen->isOnScreen()) { CString& dir = m_screen->getDraggingFileDir(); if (!dir.empty()) { LOG((CLOG_DEBUG "send file to client: %s", dir.c_str())); @@ -1747,7 +1749,7 @@ CServer::onMouseMovePrimary(SInt32 x, SInt32 y) // should we switch or not? if (isSwitchOkay(newScreen, dir, x, y, xc, yc)) { - if (m_screen->getDraggingStarted() && m_active != newScreen) { + if (m_enableDragDrop && m_screen->getDraggingStarted() && m_active != newScreen) { CString& dragFileList = m_screen->getDraggingFileDir(); size_t size = dragFileList.size() + 1; char* fileList = NULL; @@ -2329,18 +2331,23 @@ CServer::sendFileThread(void* filename) LOG((CLOG_ERR "failed sending file chunks: %s", error.what())); } - delete m_sendFileThread; m_sendFileThread = NULL; } void CServer::dragInfoReceived(UInt32 fileNum, CString content) { + // TODO: fix duplicate function from CClient + + if (!m_enableDragDrop) { + LOG((CLOG_DEBUG "drag drop not enabled, ignoring drag info.")); + return; + } + CDragInformation::parseDragInfo(m_dragFileList, fileNum, content); - LOG((CLOG_DEBUG "drag information received")); - LOG((CLOG_DEBUG "total drag file number: %i", m_dragFileList.size())); + LOG((CLOG_DEBUG "drag info received, total drag file number: %i", m_dragFileList.size())); - for(int i = 0; i < m_dragFileList.size(); ++i) { + for (int i = 0; i < m_dragFileList.size(); ++i) { LOG((CLOG_DEBUG "dragging file %i name: %s", i + 1, m_dragFileList.at(i).c_str())); } diff --git a/src/lib/server/CServer.h b/src/lib/server/CServer.h index f82a323c..c404e596 100644 --- a/src/lib/server/CServer.h +++ b/src/lib/server/CServer.h @@ -105,7 +105,7 @@ public: client (local screen) \p primaryClient. The client retains ownership of \p primaryClient. */ - CServer(CConfig& config, CPrimaryClient* primaryClient, CScreen* screen, IEventQueue* events); + CServer(CConfig& config, CPrimaryClient* primaryClient, CScreen* screen, IEventQueue* events, bool enableDragDrop); ~CServer(); #ifdef TEST_ENV @@ -472,6 +472,7 @@ private: CThread* m_writeToDropDirThread; CString m_dragFileExt; bool m_ignoreFileTransfer; + bool m_enableDragDrop; }; #endif diff --git a/src/lib/synergy/CClientApp.cpp b/src/lib/synergy/CClientApp.cpp index 8be9abf4..e3c2e430 100644 --- a/src/lib/synergy/CClientApp.cpp +++ b/src/lib/synergy/CClientApp.cpp @@ -408,7 +408,8 @@ CClientApp::openClient(const CString& name, const CNetworkAddress& address, CScr new CTCPSocketFactory(m_events, getSocketMultiplexer()), NULL, screen, - crypto); + crypto, + args().m_enableDragDrop); try { m_events->adoptHandler( diff --git a/src/lib/synergy/CPlatformScreen.h b/src/lib/synergy/CPlatformScreen.h index 92b7dd08..27fb9b09 100644 --- a/src/lib/synergy/CPlatformScreen.h +++ b/src/lib/synergy/CPlatformScreen.h @@ -97,9 +97,9 @@ public: virtual void setSequenceNumber(UInt32) = 0; virtual bool isPrimary() const = 0; - virtual void fakeDraggingFiles(CString str) { } + virtual void fakeDraggingFiles(CString str) { throw std::runtime_error("fakeDraggingFiles not implemented"); } virtual const CString& - getDropTarget() const { } + getDropTarget() const { throw std::runtime_error("getDropTarget not implemented"); } protected: //! Update mouse buttons diff --git a/src/lib/synergy/CServerApp.cpp b/src/lib/synergy/CServerApp.cpp index 938ac49c..d8e59c6e 100644 --- a/src/lib/synergy/CServerApp.cpp +++ b/src/lib/synergy/CServerApp.cpp @@ -695,7 +695,7 @@ CServerApp::openClientListener(const CNetworkAddress& address) CServer* CServerApp::openServer(CConfig& config, CPrimaryClient* primaryClient) { - CServer* server = new CServer(config, primaryClient, s_serverScreen, m_events); + CServer* server = new CServer(config, primaryClient, s_serverScreen, m_events, args().m_enableDragDrop); try { m_events->adoptHandler( m_events->forCServer().disconnected(), server, diff --git a/src/test/integtests/NetworkTests.cpp b/src/test/integtests/NetworkTests.cpp index a562c291..fe953600 100644 --- a/src/test/integtests/NetworkTests.cpp +++ b/src/test/integtests/NetworkTests.cpp @@ -130,7 +130,7 @@ TEST_F(NetworkTests, sendToClient_mockData) ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true)); ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter)); - CServer server(serverConfig, &primaryClient, &serverScreen, &m_events); + CServer server(serverConfig, &primaryClient, &serverScreen, &m_events, false); server.m_mock = true; listener.setServer(&server); @@ -142,7 +142,7 @@ TEST_F(NetworkTests, sendToClient_mockData) ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape)); ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos)); - CClient client(&m_events, "stub", serverAddress, clientSocketFactory, NULL, &clientScreen, cryptoOptions); + CClient client(&m_events, "stub", serverAddress, clientSocketFactory, NULL, &clientScreen, cryptoOptions, false); m_events.adoptHandler( m_events.forIScreen().fileRecieveCompleted(), &client, @@ -183,7 +183,7 @@ TEST_F(NetworkTests, sendToClient_mockFile) ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true)); ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter)); - CServer server(serverConfig, &primaryClient, &serverScreen, &m_events); + CServer server(serverConfig, &primaryClient, &serverScreen, &m_events, false); server.m_mock = true; listener.setServer(&server); @@ -195,7 +195,7 @@ TEST_F(NetworkTests, sendToClient_mockFile) ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape)); ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos)); - CClient client(&m_events, "stub", serverAddress, clientSocketFactory, NULL, &clientScreen, cryptoOptions); + CClient client(&m_events, "stub", serverAddress, clientSocketFactory, NULL, &clientScreen, cryptoOptions, false); m_events.adoptHandler( m_events.forIScreen().fileRecieveCompleted(), &client, @@ -231,7 +231,7 @@ TEST_F(NetworkTests, sendToServer_mockData) ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true)); ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter)); - CServer server(serverConfig, &primaryClient, &serverScreen, &m_events); + CServer server(serverConfig, &primaryClient, &serverScreen, &m_events, false); server.m_mock = true; listener.setServer(&server); @@ -243,7 +243,7 @@ TEST_F(NetworkTests, sendToServer_mockData) ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape)); ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos)); - CClient client(&m_events, "stub", serverAddress, clientSocketFactory, NULL, &clientScreen, cryptoOptions); + CClient client(&m_events, "stub", serverAddress, clientSocketFactory, NULL, &clientScreen, cryptoOptions, false); m_events.adoptHandler( m_events.forCClientListener().connected(), &listener, @@ -284,7 +284,7 @@ TEST_F(NetworkTests, sendToServer_mockFile) ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true)); ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter)); - CServer server(serverConfig, &primaryClient, &serverScreen, &m_events); + CServer server(serverConfig, &primaryClient, &serverScreen, &m_events, false); server.m_mock = true; listener.setServer(&server); @@ -296,7 +296,7 @@ TEST_F(NetworkTests, sendToServer_mockFile) ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape)); ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos)); - CClient client(&m_events, "stub", serverAddress, clientSocketFactory, NULL, &clientScreen, cryptoOptions); + CClient client(&m_events, "stub", serverAddress, clientSocketFactory, NULL, &clientScreen, cryptoOptions, false); m_events.adoptHandler( m_events.forCClientListener().connected(), &listener,