fixed: linux client crashes on file drop, even though drag and drop is disabled

This commit is contained in:
Nick Bolton 2014-02-06 18:39:12 +00:00
parent 9c3e9aab09
commit f149101d25
11 changed files with 72 additions and 62 deletions

View File

@ -51,7 +51,8 @@ CClient::CClient(IEventQueue* events,
ISocketFactory* socketFactory, ISocketFactory* socketFactory,
IStreamFilterFactory* streamFilterFactory, IStreamFilterFactory* streamFilterFactory,
CScreen* screen, CScreen* screen,
const CCryptoOptions& crypto) : const CCryptoOptions& crypto,
bool enableDragDrop) :
m_mock(false), m_mock(false),
m_name(name), m_name(name),
m_serverAddress(address), m_serverAddress(address),
@ -69,7 +70,8 @@ CClient::CClient(IEventQueue* events,
m_cryptoStream(NULL), m_cryptoStream(NULL),
m_crypto(crypto), m_crypto(crypto),
m_sendFileThread(NULL), m_sendFileThread(NULL),
m_writeToDropDirThread(NULL) m_writeToDropDirThread(NULL),
m_enableDragDrop(false)
{ {
assert(m_socketFactory != NULL); assert(m_socketFactory != NULL);
assert(m_screen != NULL); assert(m_screen != NULL);
@ -83,6 +85,8 @@ CClient::CClient(IEventQueue* events,
getEventTarget(), getEventTarget(),
new TMethodEventJob<CClient>(this, new TMethodEventJob<CClient>(this,
&CClient::handleResume)); &CClient::handleResume));
if (m_enableDragDrop) {
m_events->adoptHandler(m_events->forIScreen().fileChunkSending(), m_events->adoptHandler(m_events->forIScreen().fileChunkSending(),
this, this,
new TMethodEventJob<CClient>(this, new TMethodEventJob<CClient>(this,
@ -92,6 +96,7 @@ CClient::CClient(IEventQueue* events,
new TMethodEventJob<CClient>(this, new TMethodEventJob<CClient>(this,
&CClient::handleFileRecieveCompleted)); &CClient::handleFileRecieveCompleted));
} }
}
CClient::~CClient() CClient::~CClient()
{ {
@ -110,7 +115,6 @@ CClient::~CClient()
cleanupConnection(); cleanupConnection();
delete m_socketFactory; delete m_socketFactory;
delete m_streamFilterFactory; delete m_streamFilterFactory;
delete m_sendFileThread;
} }
void void
@ -782,10 +786,15 @@ CClient::fileChunkReceived(CString data)
void void
CClient::dragInfoReceived(UInt32 fileNum, CString data) CClient::dragInfoReceived(UInt32 fileNum, CString data)
{ {
LOG((CLOG_DEBUG "drag information received")); // TODO: fix duplicate function from CServer
LOG((CLOG_DEBUG "parsing drag info data: %s", data.c_str()));
if (!m_enableDragDrop) {
LOG((CLOG_DEBUG "drag drop not enabled, ignoring drag info."));
return;
}
CDragInformation::parseDragInfo(m_dragFileList, fileNum, data); CDragInformation::parseDragInfo(m_dragFileList, fileNum, data);
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_DEBUG2 "dragging file %i name: %s", i + 1, m_dragFileList.at(i).c_str())); 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())); LOG((CLOG_ERR "failed sending file chunks: %s", error.what()));
} }
delete m_sendFileThread;
m_sendFileThread = NULL; m_sendFileThread = NULL;
} }

View File

@ -62,7 +62,8 @@ public:
ISocketFactory* socketFactory, ISocketFactory* socketFactory,
IStreamFilterFactory* streamFilterFactory, IStreamFilterFactory* streamFilterFactory,
CScreen* screen, CScreen* screen,
const CCryptoOptions& crypto); const CCryptoOptions& crypto,
bool enableDragDrop);
~CClient(); ~CClient();
#ifdef TEST_ENV #ifdef TEST_ENV
@ -236,6 +237,7 @@ private:
CString m_dragFileExt; CString m_dragFileExt;
CThread* m_sendFileThread; CThread* m_sendFileThread;
CThread* m_writeToDropDirThread; CThread* m_writeToDropDirThread;
bool m_enableDragDrop;
}; };
#endif #endif

View File

@ -1888,12 +1888,6 @@ CMSWindowsScreen::CHotKeyItem::operator<(const CHotKeyItem& x) const
(m_keycode == x.m_keycode && m_mask < x.m_mask)); (m_keycode == x.m_keycode && m_mask < x.m_mask));
} }
void
CMSWindowsScreen::fakeDraggingFiles(CString str)
{
}
CString& CString&
CMSWindowsScreen::getDraggingFileDir() CMSWindowsScreen::getDraggingFileDir()
{ {

View File

@ -115,7 +115,6 @@ public:
virtual void setOptions(const COptionsList& options); virtual void setOptions(const COptionsList& options);
virtual void setSequenceNumber(UInt32); virtual void setSequenceNumber(UInt32);
virtual bool isPrimary() const; virtual bool isPrimary() const;
virtual void fakeDraggingFiles(CString str);
virtual CString& getDraggingFileDir(); virtual CString& getDraggingFileDir();
virtual const CString& virtual const CString&
getDropTarget() const; getDropTarget() const;

View File

@ -2095,7 +2095,6 @@ COSXScreen::CFStringRefToUTF8String(CFStringRef aString)
void void
COSXScreen::fakeDraggingFiles(CString str) COSXScreen::fakeDraggingFiles(CString str)
{ {
if (CApp::instance().argsBase().m_enableDragDrop) {
m_fakeDraggingStarted = true; m_fakeDraggingStarted = true;
#if defined(MAC_OS_X_VERSION_10_7) #if defined(MAC_OS_X_VERSION_10_7)
// TODO: use real file extension // TODO: use real file extension
@ -2104,7 +2103,6 @@ COSXScreen::fakeDraggingFiles(CString str)
LOG((CLOG_WARN "drag drop not supported")); LOG((CLOG_WARN "drag drop not supported"));
#endif #endif
} }
}
CString& CString&
COSXScreen::getDraggingFileDir() COSXScreen::getDraggingFileDir()

View File

@ -47,7 +47,7 @@
// CServer // 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_events(events),
m_mock(false), m_mock(false),
m_primaryClient(primaryClient), m_primaryClient(primaryClient),
@ -77,7 +77,8 @@ CServer::CServer(CConfig& config, CPrimaryClient* primaryClient, CScreen* screen
m_screen(screen), m_screen(screen),
m_sendFileThread(NULL), m_sendFileThread(NULL),
m_writeToDropDirThread(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 // must have a primary client and it must have a canonical name
assert(m_primaryClient != NULL); assert(m_primaryClient != NULL);
@ -166,6 +167,8 @@ CServer::CServer(CConfig& config, CPrimaryClient* primaryClient, CScreen* screen
m_inputFilter, m_inputFilter,
new TMethodEventJob<CServer>(this, new TMethodEventJob<CServer>(this,
&CServer::handleFakeInputEndEvent)); &CServer::handleFakeInputEndEvent));
if (m_enableDragDrop) {
m_events->adoptHandler(m_events->forIScreen().fileChunkSending(), m_events->adoptHandler(m_events->forIScreen().fileChunkSending(),
this, this,
new TMethodEventJob<CServer>(this, new TMethodEventJob<CServer>(this,
@ -174,6 +177,7 @@ CServer::CServer(CConfig& config, CPrimaryClient* primaryClient, CScreen* screen
this, this,
new TMethodEventJob<CServer>(this, new TMethodEventJob<CServer>(this,
&CServer::handleFileRecieveCompletedEvent)); &CServer::handleFileRecieveCompletedEvent));
}
// add connection // add connection
addClient(m_primaryClient); addClient(m_primaryClient);
@ -245,8 +249,6 @@ CServer::~CServer()
// disable and disconnect primary client // disable and disconnect primary client
m_primaryClient->disable(); m_primaryClient->disable();
removeClient(m_primaryClient); removeClient(m_primaryClient);
delete m_sendFileThread;
} }
bool bool
@ -1666,7 +1668,7 @@ CServer::onMouseUp(ButtonID id)
return; return;
} }
if (!m_screen->isOnScreen()) { if (m_enableDragDrop && !m_screen->isOnScreen()) {
CString& dir = m_screen->getDraggingFileDir(); CString& dir = m_screen->getDraggingFileDir();
if (!dir.empty()) { if (!dir.empty()) {
LOG((CLOG_DEBUG "send file to client: %s", dir.c_str())); 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? // should we switch or not?
if (isSwitchOkay(newScreen, dir, x, y, xc, yc)) { 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(); CString& dragFileList = m_screen->getDraggingFileDir();
size_t size = dragFileList.size() + 1; size_t size = dragFileList.size() + 1;
char* fileList = NULL; char* fileList = NULL;
@ -2329,16 +2331,21 @@ CServer::sendFileThread(void* filename)
LOG((CLOG_ERR "failed sending file chunks: %s", error.what())); LOG((CLOG_ERR "failed sending file chunks: %s", error.what()));
} }
delete m_sendFileThread;
m_sendFileThread = NULL; m_sendFileThread = NULL;
} }
void void
CServer::dragInfoReceived(UInt32 fileNum, CString content) 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); CDragInformation::parseDragInfo(m_dragFileList, fileNum, content);
LOG((CLOG_DEBUG "drag information received")); LOG((CLOG_DEBUG "drag info received, total drag file number: %i", m_dragFileList.size()));
LOG((CLOG_DEBUG "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())); LOG((CLOG_DEBUG "dragging file %i name: %s", i + 1, m_dragFileList.at(i).c_str()));

View File

@ -105,7 +105,7 @@ public:
client (local screen) \p primaryClient. The client retains client (local screen) \p primaryClient. The client retains
ownership of \p primaryClient. 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(); ~CServer();
#ifdef TEST_ENV #ifdef TEST_ENV
@ -472,6 +472,7 @@ private:
CThread* m_writeToDropDirThread; CThread* m_writeToDropDirThread;
CString m_dragFileExt; CString m_dragFileExt;
bool m_ignoreFileTransfer; bool m_ignoreFileTransfer;
bool m_enableDragDrop;
}; };
#endif #endif

View File

@ -408,7 +408,8 @@ CClientApp::openClient(const CString& name, const CNetworkAddress& address, CScr
new CTCPSocketFactory(m_events, getSocketMultiplexer()), new CTCPSocketFactory(m_events, getSocketMultiplexer()),
NULL, NULL,
screen, screen,
crypto); crypto,
args().m_enableDragDrop);
try { try {
m_events->adoptHandler( m_events->adoptHandler(

View File

@ -97,9 +97,9 @@ public:
virtual void setSequenceNumber(UInt32) = 0; virtual void setSequenceNumber(UInt32) = 0;
virtual bool isPrimary() const = 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& virtual const CString&
getDropTarget() const { } getDropTarget() const { throw std::runtime_error("getDropTarget not implemented"); }
protected: protected:
//! Update mouse buttons //! Update mouse buttons

View File

@ -695,7 +695,7 @@ CServerApp::openClientListener(const CNetworkAddress& address)
CServer* CServer*
CServerApp::openServer(CConfig& config, CPrimaryClient* primaryClient) 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 { try {
m_events->adoptHandler( m_events->adoptHandler(
m_events->forCServer().disconnected(), server, m_events->forCServer().disconnected(), server,

View File

@ -130,7 +130,7 @@ TEST_F(NetworkTests, sendToClient_mockData)
ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true)); ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true));
ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter)); 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; server.m_mock = true;
listener.setServer(&server); listener.setServer(&server);
@ -142,7 +142,7 @@ TEST_F(NetworkTests, sendToClient_mockData)
ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape)); ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape));
ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos)); 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.adoptHandler(
m_events.forIScreen().fileRecieveCompleted(), &client, m_events.forIScreen().fileRecieveCompleted(), &client,
@ -183,7 +183,7 @@ TEST_F(NetworkTests, sendToClient_mockFile)
ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true)); ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true));
ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter)); 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; server.m_mock = true;
listener.setServer(&server); listener.setServer(&server);
@ -195,7 +195,7 @@ TEST_F(NetworkTests, sendToClient_mockFile)
ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape)); ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape));
ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos)); 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.adoptHandler(
m_events.forIScreen().fileRecieveCompleted(), &client, m_events.forIScreen().fileRecieveCompleted(), &client,
@ -231,7 +231,7 @@ TEST_F(NetworkTests, sendToServer_mockData)
ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true)); ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true));
ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter)); 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; server.m_mock = true;
listener.setServer(&server); listener.setServer(&server);
@ -243,7 +243,7 @@ TEST_F(NetworkTests, sendToServer_mockData)
ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape)); ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape));
ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos)); 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.adoptHandler(
m_events.forCClientListener().connected(), &listener, m_events.forCClientListener().connected(), &listener,
@ -284,7 +284,7 @@ TEST_F(NetworkTests, sendToServer_mockFile)
ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true)); ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true));
ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter)); 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; server.m_mock = true;
listener.setServer(&server); listener.setServer(&server);
@ -296,7 +296,7 @@ TEST_F(NetworkTests, sendToServer_mockFile)
ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape)); ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape));
ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos)); 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.adoptHandler(
m_events.forCClientListener().connected(), &listener, m_events.forCClientListener().connected(), &listener,