]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/sckipc.cpp
wxTextCtrk::GetRange() shouldn't crash on out of range request
[wxWidgets.git] / src / common / sckipc.cpp
index 9a9b4c62b8dc1fec3470820418875fdd5bc7fb6f..9fdd8343eff012cd2b08fc9c9015a5868e397fd4 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        sckipc.cpp
+// Name:        src/common/sckipc.cpp
 // Purpose:     Interprocess communication implementation (wxSocket version)
 // Author:      Julian Smart
 // Modified by: Guilhem Lavaux (big rewrite) May 1997, 1998
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
-#pragma hdrstop
+    #pragma hdrstop
 #endif
 
+#if wxUSE_SOCKETS && wxUSE_IPC && wxUSE_STREAMS
+
+#include "wx/sckipc.h"
+
 #ifndef WX_PRECOMP
-#include "wx/log.h"
+    #include "wx/log.h"
+    #include "wx/event.h"
+    #include "wx/module.h"
 #endif
 
-#if wxUSE_SOCKETS && wxUSE_IPC && wxUSE_STREAMS
-
 #include <stdlib.h>
 #include <stdio.h>
 #include <errno.h>
 
 #include "wx/socket.h"
-#include "wx/sckipc.h"
-#include "wx/module.h"
-#include "wx/event.h"
 
 // --------------------------------------------------------------------------
 // macros and constants
@@ -68,7 +69,7 @@ enum
 #endif
 
 // All sockets will be created with the following flags
-#define SCKIPC_FLAGS (wxSOCKET_WAITALL)
+#define SCKIPC_FLAGS (wxSOCKET_WAITALL|wxSOCKET_REUSEADDR)
 
 // headers needed for umask()
 #ifdef __UNIX_LIKE__
@@ -85,7 +86,7 @@ static wxSockAddress *
 GetAddressFromName(const wxString& serverName, const wxString& host = wxEmptyString)
 {
     // we always use INET sockets under non-Unix systems
-#if defined(__UNIX__) && !defined(__WINDOWS__) && !defined(__WINE__) && (!defined(__WXMAC__) || defined(__DARWIN__))
+#if defined(__UNIX__) && !defined(__WINDOWS__) && !defined(__WINE__)
     // under Unix, if the server name looks like a path, create a AF_UNIX
     // socket instead of AF_INET one
     if ( serverName.Find(_T('/')) != wxNOT_FOUND )
@@ -163,15 +164,15 @@ wxConnectionBase *wxTCPClient::MakeConnection (const wxString& host,
                                                const wxString& serverName,
                                                const wxString& topic)
 {
+  wxSockAddress *addr = GetAddressFromName(serverName, host);
+  if ( !addr )
+      return NULL;
+
   wxSocketClient *client = new wxSocketClient(SCKIPC_FLAGS);
   wxSocketStream *stream = new wxSocketStream(*client);
   wxDataInputStream *data_is = new wxDataInputStream(*stream);
   wxDataOutputStream *data_os = new wxDataOutputStream(*stream);
 
-  wxSockAddress *addr = GetAddressFromName(serverName, host);
-  if ( !addr )
-      return NULL;
-
   bool ok = client->Connect(*addr);
   delete addr;
 
@@ -343,7 +344,7 @@ wxTCPConnection::wxTCPConnection () : wxConnectionBase()
   m_codeco   = NULL;
 }
 
-wxTCPConnection::wxTCPConnection(wxChar *buffer, int size)
+wxTCPConnection::wxTCPConnection(void *buffer, size_t size)
        : wxConnectionBase(buffer, size)
 {
   m_sock     = NULL;
@@ -355,15 +356,17 @@ wxTCPConnection::wxTCPConnection(wxChar *buffer, int size)
 wxTCPConnection::~wxTCPConnection ()
 {
   Disconnect();
-  wxDELETE(m_codeci);
-  wxDELETE(m_codeco);
-  wxDELETE(m_sockstrm);
 
   if (m_sock)
   {
     m_sock->SetClientData(NULL);
     m_sock->Destroy();
   }
+
+  /* Delete after destroy */
+  wxDELETE(m_codeci);
+  wxDELETE(m_codeco);
+  wxDELETE(m_sockstrm);
 }
 
 void wxTCPConnection::Compress(bool WXUNUSED(on))
@@ -378,14 +381,19 @@ bool wxTCPConnection::Disconnect ()
       return true;
   // Send the the disconnect message to the peer.
   m_codeco->Write8(IPC_DISCONNECT);
-  m_sock->Notify(false);
-  m_sock->Close();
+
+  if ( m_sock )
+  {
+      m_sock->Notify(false);
+      m_sock->Close();
+  }
+
   SetConnected(false);
 
   return true;
 }
 
-bool wxTCPConnection::Execute(const wxChar *data, int size, wxIPCFormat format)
+bool wxTCPConnection::DoExecute(const void *data, size_t size, wxIPCFormat format)
 {
   if (!m_sock->IsConnected())
     return false;
@@ -394,16 +402,13 @@ bool wxTCPConnection::Execute(const wxChar *data, int size, wxIPCFormat format)
   m_codeco->Write8(IPC_EXECUTE);
   m_codeco->Write8(format);
 
-  if (size < 0)
-    size = (wxStrlen(data) + 1) * sizeof(wxChar);    // includes final NUL
-
   m_codeco->Write32(size);
   m_sockstrm->Write(data, size);
 
   return true;
 }
 
-wxChar *wxTCPConnection::Request (const wxString& item, int *size, wxIPCFormat format)
+const void *wxTCPConnection::Request (const wxString& item, size_t *size, wxIPCFormat format)
 {
   if (!m_sock->IsConnected())
     return NULL;
@@ -420,10 +425,9 @@ wxChar *wxTCPConnection::Request (const wxString& item, int *size, wxIPCFormat f
     return NULL;
   else
   {
-    size_t s;
+    size_t s = m_codeci->Read32();
 
-    s = m_codeci->Read32();
-    wxChar *data = GetBufferAtLeast( s );
+    void *data = GetBufferAtLeast( s );
     wxASSERT_MSG(data != NULL,
                  _T("Buffer too small in wxTCPConnection::Request") );
     m_sockstrm->Read(data, s);
@@ -434,7 +438,7 @@ wxChar *wxTCPConnection::Request (const wxString& item, int *size, wxIPCFormat f
   }
 }
 
-bool wxTCPConnection::Poke (const wxString& item, wxChar *data, int size, wxIPCFormat format)
+bool wxTCPConnection::DoPoke (const wxString& item, const void *data, size_t size, wxIPCFormat format)
 {
   if (!m_sock->IsConnected())
     return false;
@@ -443,9 +447,6 @@ bool wxTCPConnection::Poke (const wxString& item, wxChar *data, int size, wxIPCF
   m_codeco->WriteString(item);
   m_codeco->Write8(format);
 
-  if (size < 0)
-    size = (wxStrlen(data) + 1) * sizeof(wxChar);    // includes final NUL
-
   m_codeco->Write32(size);
   m_sockstrm->Write(data, size);
 
@@ -489,8 +490,8 @@ bool wxTCPConnection::StopAdvise (const wxString& item)
 }
 
 // Calls that SERVER can make
-bool wxTCPConnection::Advise (const wxString& item,
-                              wxChar *data, int size, wxIPCFormat format)
+bool wxTCPConnection::DoAdvise (const wxString& item,
+                                const void *data, size_t size, wxIPCFormat format)
 {
   if (!m_sock->IsConnected())
     return false;
@@ -499,9 +500,6 @@ bool wxTCPConnection::Advise (const wxString& item,
   m_codeco->WriteString(item);
   m_codeco->Write8(format);
 
-  if (size < 0)
-    size = (wxStrlen(data) + 1) * sizeof(wxChar);    // includes final NUL
-
   m_codeco->Write32(size);
   m_sockstrm->Write(data, size);
 
@@ -520,6 +518,9 @@ END_EVENT_TABLE()
 void wxTCPEventHandler::Client_OnRequest(wxSocketEvent &event)
 {
   wxSocketBase *sock = event.GetSocket();
+  if (!sock) {         /* No socket, no glory */
+    return ;
+  }
   wxSocketNotify evt = event.GetSocketEvent();
   wxTCPConnection *connection = (wxTCPConnection *)(sock->GetClientData());
 
@@ -552,12 +553,13 @@ void wxTCPEventHandler::Client_OnRequest(wxSocketEvent &event)
   {
   case IPC_EXECUTE:
   {
-    wxChar *data;
+    void *data;
     size_t size;
     wxIPCFormat format;
 
     format = (wxIPCFormat)codeci->Read8();
     size = codeci->Read32();
+    
     data = connection->GetBufferAtLeast( size );
     wxASSERT_MSG(data != NULL,
                  _T("Buffer too small in wxTCPEventHandler::Client_OnRequest") );
@@ -569,14 +571,10 @@ void wxTCPEventHandler::Client_OnRequest(wxSocketEvent &event)
   }
   case IPC_ADVISE:
   {
-    wxChar *data;
-    size_t size;
-    wxIPCFormat format;
-
     item = codeci->ReadString();
-    format = (wxIPCFormat)codeci->Read8();
-    size = codeci->Read32();
-    data = connection->GetBufferAtLeast( size );
+    wxIPCFormat format = (wxIPCFormat)codeci->Read8();
+    size_t size = codeci->Read32();
+    void *data = connection->GetBufferAtLeast( size );
     wxASSERT_MSG(data != NULL,
                  _T("Buffer too small in wxTCPEventHandler::Client_OnRequest") );
     sockstrm->Read(data, size);
@@ -611,14 +609,10 @@ void wxTCPEventHandler::Client_OnRequest(wxSocketEvent &event)
   }
   case IPC_POKE:
   {
-    wxIPCFormat format;
-    size_t size;
-    wxChar *data;
-
     item = codeci->ReadString();
-    format = (wxIPCFormat)codeci->Read8();
-    size = codeci->Read32();
-    data = connection->GetBufferAtLeast( size );
+    wxIPCFormat format = (wxIPCFormat)codeci->Read8();
+    size_t size = codeci->Read32();
+    void *data = connection->GetBufferAtLeast( size );
     wxASSERT_MSG(data != NULL,
                  _T("Buffer too small in wxTCPEventHandler::Client_OnRequest") );
     sockstrm->Read(data, size);
@@ -634,15 +628,28 @@ void wxTCPEventHandler::Client_OnRequest(wxSocketEvent &event)
     item = codeci->ReadString();
     format = (wxIPCFormat)codeci->Read8();
 
-    int user_size = -1;
-    wxChar *user_data = connection->OnRequest (topic_name, item, &user_size, format);
+    size_t user_size = wxNO_LEN;
+    const void *user_data = connection->OnRequest (topic_name, item, &user_size, format);
 
     if (user_data)
     {
       codeco->Write8(IPC_REQUEST_REPLY);
 
-      if (user_size == -1)
-        user_size = (wxStrlen(user_data) + 1) * sizeof(wxChar);    // includes final NUL
+      if (user_size == wxNO_LEN)
+      {
+        switch (format)
+        {
+          case wxIPC_TEXT:
+          case wxIPC_UTF8TEXT:
+            user_size = strlen((const char *)user_data) + 1;  // includes final NUL
+            break;
+          case wxIPC_UNICODETEXT:
+            user_size = (wcslen((const wchar_t *)user_data) + 1) * sizeof(wchar_t);  // includes final NUL
+            break;
+          default:
+            user_size = 0;
+        }
+      }
 
       codeco->Write32(user_size);
       sockstrm->Write(user_data, user_size);
@@ -669,6 +676,9 @@ void wxTCPEventHandler::Client_OnRequest(wxSocketEvent &event)
 void wxTCPEventHandler::Server_OnRequest(wxSocketEvent &event)
 {
   wxSocketServer *server = (wxSocketServer *) event.GetSocket();
+  if (!server) {               /* No server, Then exit */
+         return ;
+  }
   wxTCPServer *ipcserv = (wxTCPServer *) server->GetClientData();
 
   // This socket is being deleted; skip this event
@@ -680,6 +690,9 @@ void wxTCPEventHandler::Server_OnRequest(wxSocketEvent &event)
 
   // Accept the connection, getting a new socket
   wxSocketBase *sock = server->Accept();
+  if (!sock) {         /* No socket, no glory */
+         return ;
+  }
   if (!sock->Ok())
   {
     sock->Destroy();
@@ -752,4 +765,4 @@ IMPLEMENT_DYNAMIC_CLASS(wxTCPEventHandlerModule, wxModule)
 
 
 #endif
-    // wxUSE_SOCKETS && wxUSE_IPC
+   // wxUSE_SOCKETS && wxUSE_IPC && wxUSE_STREAMS