summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Gorse <mgorse@suse.com>2022-04-07 12:43:59 -0500
committerMike Gorse <mgorse@suse.com>2022-04-08 09:09:56 -0500
commit4766e3be06cef19c7bc647eae0a3af61b254dc38 (patch)
tree2f73fae165d00492c7cbfba736d7b4548d3b5b30
parent6a36042d828c8edc3976eec6deb9a4e7a7a7b037 (diff)
downloadat-spi2-atk-4766e3be06cef19c7bc647eae0a3af61b254dc38.tar.gz
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
-rw-r--r--atk-adaptor/bridge.c42
-rw-r--r--droute/droute.c26
-rw-r--r--droute/droute.h4
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,