[at-spi2-atk] droute: handle unimplemented interfaces for GetAll and introspection



commit 4766e3be06cef19c7bc647eae0a3af61b254dc38
Author: Mike Gorse <mgorse suse com>
Date:   Thu Apr 7 12:43:59 2022 -0500

    droute: handle unimplemented interfaces for GetAll and introspection
    
    The iterator for retrieving all properties doesn't handle a getter failing,
    which happens if the AtkObject doesn't implement the atk interface
    corresponding to the dbus interface. This leads to the application aborting
    on account of a malformed DBusMessage.
    
    Helps #20

 atk-adaptor/bridge.c | 42 +++++++++++++++++++++++++++++++++++++++++-
 droute/droute.c      | 26 ++++++++++++++++++++------
 droute/droute.h      |  4 +++-
 3 files changed, 64 insertions(+), 8 deletions(-)
---
diff --git a/atk-adaptor/bridge.c b/atk-adaptor/bridge.c
index bdb4c704..f808acb0 100644
--- a/atk-adaptor/bridge.c
+++ b/atk-adaptor/bridge.c
@@ -980,6 +980,45 @@ spi_atk_activate ()
     }
 }
 
+static gboolean
+spi_object_has_dbus_interface (void *obj, const char *interface)
+{
+  if (!strcmp (interface, ATSPI_DBUS_INTERFACE_ACCESSIBLE))
+    return TRUE;
+  if (!strcmp (interface, ATSPI_DBUS_INTERFACE_ACTION))
+    return ATK_IS_ACTION (obj);
+  if (!strcmp (interface, ATSPI_DBUS_INTERFACE_COLLECTION))
+    return TRUE;
+  if (!strcmp (interface, ATSPI_DBUS_INTERFACE_COMPONENT))
+    return ATK_IS_COMPONENT (obj);
+  if (!strcmp (interface, ATSPI_DBUS_INTERFACE_DOCUMENT))
+    return ATK_IS_DOCUMENT (obj);
+  if (!strcmp (interface, ATSPI_DBUS_INTERFACE_EDITABLE_TEXT))
+    return ATK_IS_EDITABLE_TEXT (obj);
+  if (!strcmp (interface, ATSPI_DBUS_INTERFACE_HYPERLINK))
+    return ATK_IS_HYPERLINK (obj);
+  if (!strcmp (interface, ATSPI_DBUS_INTERFACE_HYPERTEXT))
+    return ATK_IS_HYPERTEXT (obj);
+  if (!strcmp (interface, ATSPI_DBUS_INTERFACE_IMAGE))
+    return ATK_IS_IMAGE (obj);
+  if (!strcmp (interface, ATSPI_DBUS_INTERFACE_SELECTION))
+    return ATK_IS_SELECTION (obj);
+  if (!strcmp (interface, ATSPI_DBUS_INTERFACE_SOCKET))
+    return TRUE;
+  if (!strcmp (interface, ATSPI_DBUS_INTERFACE_TABLE))
+    return ATK_IS_TABLE (obj);
+  if (!strcmp (interface, ATSPI_DBUS_INTERFACE_TABLE_CELL))
+    return ATK_IS_TABLE_CELL (obj);
+  if (!strcmp (interface, ATSPI_DBUS_INTERFACE_TEXT))
+    return ATK_IS_TEXT (obj);
+  if (!strcmp (interface, ATSPI_DBUS_INTERFACE_VALUE))
+    return ATK_IS_VALUE (obj);
+
+  return FALSE;
+
+    return TRUE;
+}
+
 /**
  * atk_bridge_adaptor_init: initializes the atk bridge adaptor
  *
@@ -1090,7 +1129,8 @@ atk_bridge_adaptor_init (gint * argc, gchar ** argv[])
                              introspect_children_cb,
                              NULL,
                              (DRouteGetDatumFunction)
-                             spi_global_register_path_to_object);
+                             spi_global_register_path_to_object,
+                             spi_object_has_dbus_interface);
 
 
   /* Register all interfaces with droute and set up application accessible db */
diff --git a/droute/droute.c b/droute/droute.c
index 3955a91a..14e77718 100644
--- a/droute/droute.c
+++ b/droute/droute.c
@@ -60,6 +60,7 @@ struct _DRoutePath
     void *introspect_children_data;
     void                   *user_data;
     DRouteGetDatumFunction  get_datum;
+    DRouteQueryInterfaceFunction query_interface_cb;
 };
 
 /*---------------------------------------------------------------------------*/
@@ -87,7 +88,8 @@ path_new (DRouteContext *cnx,
           void    *user_data,
           DRouteIntrospectChildrenFunction introspect_children_cb,
           void *introspect_children_data,
-          DRouteGetDatumFunction get_datum)
+          DRouteGetDatumFunction get_datum,
+          DRouteQueryInterfaceFunction query_interface_cb)
 {
     DRoutePath *new_path;
 
@@ -113,6 +115,7 @@ path_new (DRouteContext *cnx,
     new_path->introspect_children_data = introspect_children_data;
     new_path->user_data = user_data;
     new_path->get_datum = get_datum;
+    new_path->query_interface_cb = query_interface_cb;
 
     return new_path;
 }
@@ -177,7 +180,8 @@ droute_add_one (DRouteContext *cnx,
 {
     DRoutePath *new_path;
 
-    new_path = path_new (cnx, path, FALSE, (void *)data, NULL, NULL, NULL);
+    new_path = path_new (cnx, path, FALSE, (void *)data, NULL, NULL, NULL,
+                         NULL);
 
     g_ptr_array_add (cnx->registered_paths, new_path);
     return new_path;
@@ -189,13 +193,14 @@ droute_add_many (DRouteContext *cnx,
                  const void    *data,
                  DRouteIntrospectChildrenFunction introspect_children_cb,
                  void *introspect_children_data,
-                 const DRouteGetDatumFunction get_datum)
+                 const DRouteGetDatumFunction get_datum,
+                 const DRouteQueryInterfaceFunction query_interface_cb)
 {
     DRoutePath *new_path;
 
     new_path = path_new (cnx, path, TRUE, (void *) data,
                          introspect_children_cb, introspect_children_data,
-                         get_datum);
+                         get_datum, query_interface_cb);
 
     g_ptr_array_add (cnx->registered_paths, new_path);
     return new_path;
@@ -272,7 +277,11 @@ impl_prop_GetAll (DBusMessage *message,
         return ret;
       }
 
-    reply = dbus_message_new_method_return (message);
+    if (path->query_interface_cb &&
+        !path->query_interface_cb (datum, iface))
+      return dbus_message_new_error (message, DBUS_ERROR_UNKNOWN_PROPERTY, "Property unavailable");
+
+      reply = dbus_message_new_method_return (message);
     if (!reply)
         oom ();
 
@@ -475,6 +484,7 @@ handle_introspection (DBusConnection *bus,
     GString *output;
     gchar *final;
     gint i;
+    void *datum;
 
     DBusMessage *reply;
 
@@ -487,11 +497,15 @@ handle_introspection (DBusConnection *bus,
 
     g_string_append_printf(output, introspection_node_element, pathstr);
 
-    if (!path->get_datum || path_get_datum (path, pathstr))
+    if (!path->get_datum || (datum = path_get_datum (path, pathstr)) != NULL)
       {
         for (i=0; i < path->introspection->len; i++)
           {
+            gchar *interface = (gchar *) g_ptr_array_index (path->interfaces, i);
             gchar *introspect = (gchar *) g_ptr_array_index (path->introspection, i);
+            if (path->query_interface_cb &&
+                !path->query_interface_cb (datum, interface))
+              continue;
             g_string_append (output, introspect);
           }
       }
diff --git a/droute/droute.h b/droute/droute.h
index 68c113d0..506fef1b 100644
--- a/droute/droute.h
+++ b/droute/droute.h
@@ -34,6 +34,7 @@ typedef dbus_bool_t  (*DRoutePropertyFunction) (DBusMessageIter *, void *);
 typedef gchar *(*DRouteIntrospectChildrenFunction) (const char *, void *);
 
 typedef void        *(*DRouteGetDatumFunction) (const char *, void *);
+typedef gboolean    (*DRouteQueryInterfaceFunction) (void *, const char *);
 
 typedef struct _DRouteMethod DRouteMethod;
 struct _DRouteMethod
@@ -75,7 +76,8 @@ droute_add_many (DRouteContext *cnx,
                  const void    *data,
                  DRouteIntrospectChildrenFunction introspect_children_cb,
                  void *introspect_children_data,
-                 const DRouteGetDatumFunction get_datum);
+                 const DRouteGetDatumFunction get_datum,
+                 const DRouteQueryInterfaceFunction query_interface_cb);
 
 void
 droute_path_add_interface (DRoutePath *path,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]