Fix off-by-one malloc error in dec_synth_keystring
[platform/core/uifw/at-spi2-atk.git] / registryd / deviceeventcontroller.c
index f5d6fb6..8ca6699 100644 (file)
 #include <gdk/gdkwindow.h>
 
 #include <atk-adaptor/spi-private.h>
-#include <atk-adaptor/keymasks.h>
+#include <spi-common/keymasks.h>
 #include <droute/droute.h>
 #include <spi-common/spi-dbus.h>
 #include <spi-common/spi-types.h>
 
 #include "deviceeventcontroller.h"
 #include "reentrant-list.h"
-#include "libspi/keymasks.h"
 
 KeySym ucs2keysym (long ucs);
 long keysym2ucs(KeySym keysym); 
@@ -108,7 +107,7 @@ typedef struct {
 } DEControllerGrabMask;
 
 typedef struct {
-  char *app_path;
+  char *bus_name;
   char *path;
   SpiDeviceTypeCategory type;
   gulong types;
@@ -650,7 +649,7 @@ spi_dec_translate_mask (Accessibility_ControllerEventMask mask)
 }
 
 static DEControllerKeyListener *
-spi_dec_key_listener_new (const char *app_path,
+spi_dec_key_listener_new (const char *bus_name,
                          const char *path,
                          GSList *keys,
                          const Accessibility_ControllerEventMask mask,
@@ -658,7 +657,7 @@ spi_dec_key_listener_new (const char *app_path,
                          const Accessibility_EventListenerMode  *mode)
 {
   DEControllerKeyListener *key_listener = g_new0 (DEControllerKeyListener, 1);
-  key_listener->listener.app_path = g_strdup(app_path);
+  key_listener->listener.bus_name = g_strdup(bus_name);
   key_listener->listener.path = g_strdup(path);
   key_listener->listener.type = SPI_DEVICE_TYPE_KBD;
   key_listener->keys = keys;
@@ -684,12 +683,12 @@ spi_dec_key_listener_new (const char *app_path,
 }
 
 static DEControllerListener *
-spi_dec_listener_new (const char *app_path,
+spi_dec_listener_new (const char *bus_name,
                      const char *path,
                      dbus_uint32_t types)
 {
   DEControllerListener *listener = g_new0 (DEControllerListener, 1);
-  listener->app_path = g_strdup(app_path);
+  listener->bus_name = g_strdup(bus_name);
   listener->path = g_strdup(path);
   listener->type = SPI_DEVICE_TYPE_MOUSE;
   listener->types = types;
@@ -700,7 +699,7 @@ static DEControllerListener *
 spi_listener_clone (DEControllerListener *listener)
 {
   DEControllerListener *clone = g_new0 (DEControllerListener, 1);
-  clone->app_path = g_strdup (listener->app_path);
+  clone->bus_name = g_strdup (listener->bus_name);
   clone->path = g_strdup (listener->path);
   clone->type = listener->type;
   clone->types = listener->types;
@@ -731,7 +730,7 @@ static DEControllerKeyListener *
 spi_key_listener_clone (DEControllerKeyListener *key_listener)
 {
   DEControllerKeyListener *clone = g_new0 (DEControllerKeyListener, 1);
-  clone->listener.app_path = g_strdup (key_listener->listener.app_path);
+  clone->listener.bus_name = g_strdup (key_listener->listener.bus_name);
   clone->listener.path = g_strdup (key_listener->listener.path);
   clone->listener.type = SPI_DEVICE_TYPE_KBD;
   clone->keys = keylist_clone (key_listener->keys);
@@ -778,14 +777,14 @@ static void
 spi_listener_clone_free (DEControllerListener *clone)
 {
   g_free (clone->path);
-  g_free (clone->app_path);
+  g_free (clone->bus_name);
   g_free (clone);
 }
 
 static void
 spi_dec_listener_free (DEControllerListener    *listener)
 {
-  g_free (listener->app_path);
+  g_free (listener->bus_name);
   g_free (listener->path);
   if (listener->type == SPI_DEVICE_TYPE_KBD) 
     spi_key_listener_data_free ((DEControllerKeyListener *) listener);
@@ -918,6 +917,7 @@ spi_controller_register_device_listener (SpiDEController      *controller,
 
       controller->key_listeners = g_list_prepend (controller->key_listeners,
                                                  key_listener);
+      spi_dbus_add_disconnect_match (controller->registry->droute.bus, key_listener->listener.bus_name);
       if (key_listener->mode->global)
         {
          return spi_controller_register_global_keygrabs (controller, key_listener);    
@@ -927,6 +927,7 @@ spi_controller_register_device_listener (SpiDEController      *controller,
       break;
   case SPI_DEVICE_TYPE_MOUSE:
       controller->mouse_listeners = g_list_prepend (controller->mouse_listeners, listener);
+      spi_dbus_add_disconnect_match (controller->registry->droute.bus, listener->bus_name);
       break;
   default:
       DBG (1, g_warning ("listener registration for unknown device type.\n"));
@@ -937,12 +938,12 @@ spi_controller_register_device_listener (SpiDEController      *controller,
 
 static gboolean Accessibility_DeviceEventListener_notifyEvent(SpiRegistry *registry, DEControllerListener *listener, const Accessibility_DeviceEvent *key_event)
 {
-  DBusMessage *message = dbus_message_new_method_call(listener->app_path, listener->path, "org.freedesktop.atspi.Registry", "notifyEvent");
+  DBusMessage *message = dbus_message_new_method_call(listener->bus_name, listener->path, "org.freedesktop.atspi.Registry", "notifyEvent");
   DBusError error;
   dbus_bool_t consumed = FALSE;
 
   dbus_error_init(&error);
-  if (spi_dbus_marshall_deviceEvent(message, key_event))
+  if (spi_dbus_marshal_deviceEvent(message, key_event))
   {
     // TODO: Evaluate performance: perhaps rework this whole architecture
     // to avoid blocking calls
@@ -1875,10 +1876,11 @@ remove_listener_cb (GList * const *list,
   DEControllerListener  *listener = (*list)->data;
   RemoveListenerClosure *ctx = user_data;
 
-  if (!strcmp(ctx->listener->app_path, listener->app_path) &&
+  if (!strcmp(ctx->listener->bus_name, listener->bus_name) &&
       !strcmp(ctx->listener->path, listener->path))
     {
       spi_re_entrant_list_delete_link (list);
+      spi_dbus_remove_disconnect_match (ctx->bus, listener->bus_name);
       spi_dec_listener_free (listener);
     }
 
@@ -1892,7 +1894,7 @@ copy_key_listener_cb (GList * const *list,
   DEControllerKeyListener  *key_listener = (*list)->data;
   RemoveListenerClosure    *ctx = user_data;
 
-  if (!strcmp(ctx->listener->app_path, key_listener->listener.app_path) &&
+  if (!strcmp(ctx->listener->bus_name, key_listener->listener.bus_name) &&
       !strcmp(ctx->listener->path, key_listener->listener.path))
     {
       /* TODO: FIXME aggregate keys in case the listener is registered twice */
@@ -1941,6 +1943,31 @@ spi_deregister_controller_key_listener (SpiDEController            *controller,
 
 }
 
+void
+spi_remove_device_listeners (SpiDEController *controller, const char *bus_name)
+{
+  GList *l, *tmp;
+
+  for (l = controller->mouse_listeners; l; l = tmp)
+  {
+    DEControllerListener *listener = l->data;
+    tmp = l->next;
+    if (!strcmp (listener->bus_name, bus_name))
+    {
+      spi_controller_deregister_device_listener (controller, listener);
+    }
+  }
+  for (l = controller->key_listeners; l; l = tmp)
+  {
+    DEControllerKeyListener *key_listener = l->data;
+    tmp = l->next;
+    if (!strcmp (key_listener->listener.bus_name, bus_name))
+    {
+      spi_deregister_controller_key_listener (controller, key_listener);
+    }
+  }
+}
+
 /*
  * DBus Accessibility::DEController::deregisterKeystrokeListener
  *     method implementation
@@ -2254,7 +2281,7 @@ dec_synth_keystring (SpiDEController *controller, const char *keystring)
        gboolean retval = TRUE;
        const gchar *c;
 
-       maxlen = strlen (keystring);
+       maxlen = strlen (keystring) + 1;
        keysyms = g_new0 (KeySym, maxlen);
        if (!(keystring && *keystring && g_utf8_validate (keystring, -1, &c))) { 
                retval = FALSE;
@@ -2475,7 +2502,7 @@ impl_notify_listeners_sync (DBusConnection *bus, DBusMessage *message, void *use
   dbus_bool_t ret;
   DBusMessage *reply;
 
-  if (!spi_dbus_demarshall_deviceEvent(message, &event))
+  if (!spi_dbus_demarshal_deviceEvent(message, &event))
   {
     return spi_dbus_general_error (message);
   }
@@ -2502,7 +2529,7 @@ impl_notify_listeners_async (DBusConnection *bus, DBusMessage *message, void *us
   Accessibility_DeviceEvent event;
   DBusMessage *reply;
 
-  if (!spi_dbus_demarshall_deviceEvent(message, &event))
+  if (!spi_dbus_demarshal_deviceEvent(message, &event))
   {
     return spi_dbus_general_error (message);
   }
@@ -2690,6 +2717,6 @@ static DRouteMethod methods[] =
 void
 spi_registry_initialize_dec_interface (DRouteData * data)
 {
-  droute_add_interface (data, "org.freedesktop.atspi.DeviceEventController", methods,
+  droute_add_interface (data, SPI_DBUS_INTERFACE_DEC, methods,
                        NULL, NULL, NULL);
 };