From 4766e3be06cef19c7bc647eae0a3af61b254dc38 Mon Sep 17 00:00:00 2001 From: Mike Gorse Date: Thu, 7 Apr 2022 12:43:59 -0500 Subject: 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 bdb4c70..f808acb 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 3955a91..14e7771 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 68c113d..506fef1 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, -- cgit v1.2.1