[gjs: 11/13] gdbus: Do some sanity checks in DBus skeleton



commit 6899ded621508523f4efe619cfe4954340908fd8
Author: Philip Chimento <philip chimento gmail com>
Date:   Sat Apr 20 15:24:46 2019 -0700

    gdbus: Do some sanity checks in DBus skeleton
    
    The GDBusImplementation callbacks (method_call, get_property,
    set_property) are passed lots of information such as the connection,
    interface name, method name, etc. Since this information is passed in,
    we may as well do some sanity checks with it: e.g. that the object is
    exported on the DBus connection that it received the callback from.
    
    This was spotted by compiling with -Wunused-parameter.

 libgjs-private/gjs-gdbus-wrapper.c | 66 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)
---
diff --git a/libgjs-private/gjs-gdbus-wrapper.c b/libgjs-private/gjs-gdbus-wrapper.c
index 2ad5e6bc..c11b0b0c 100644
--- a/libgjs-private/gjs-gdbus-wrapper.c
+++ b/libgjs-private/gjs-gdbus-wrapper.c
@@ -41,12 +41,66 @@ G_DEFINE_TYPE_WITH_PRIVATE(GjsDBusImplementation, gjs_dbus_implementation,
 _Pragma("GCC diagnostic pop")
 #endif
 
+static gboolean gjs_dbus_implementation_check_interface(
+    GjsDBusImplementation* self, GDBusConnection* connection,
+    const char* object_path, const char* interface_name, GError** error) {
+    const char* exported_object_path;
+
+    if (!g_dbus_interface_skeleton_has_connection(
+            G_DBUS_INTERFACE_SKELETON(self), connection)) {
+        g_set_error_literal(error, G_DBUS_ERROR, G_DBUS_ERROR_DISCONNECTED,
+                            "Wrong connection");
+        return FALSE;
+    }
+    exported_object_path = g_dbus_interface_skeleton_get_object_path(
+        G_DBUS_INTERFACE_SKELETON(self));
+    if (!exported_object_path || strcmp(object_path, exported_object_path)) {
+        g_set_error(error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_OBJECT,
+                    "Wrong object path %s for %s", object_path,
+                    exported_object_path);
+        return FALSE;
+    }
+    if (strcmp(interface_name, self->priv->ifaceinfo->name) != 0) {
+        g_set_error(error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_INTERFACE,
+                    "Unknown interface %s on %s", interface_name,
+                    self->priv->ifaceinfo->name);
+        return FALSE;
+    }
+    return TRUE;
+}
+
+static gboolean gjs_dbus_implementation_check_property(
+    GjsDBusImplementation* self, const char* interface_name,
+    const char* property_name, GError** error) {
+    if (!g_dbus_interface_info_lookup_property(self->priv->ifaceinfo,
+                                               property_name)) {
+        g_set_error(error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_PROPERTY,
+                    "Unknown property %s on %s", property_name, interface_name);
+        return FALSE;
+    }
+    return TRUE;
+}
+
 static void gjs_dbus_implementation_method_call(
     GDBusConnection* connection, const char* sender G_GNUC_UNUSED,
     const char* object_path, const char* interface_name,
     const char* method_name, GVariant* parameters,
     GDBusMethodInvocation* invocation, void* user_data) {
     GjsDBusImplementation *self = GJS_DBUS_IMPLEMENTATION (user_data);
+    GError* error = NULL;
+
+    if (!gjs_dbus_implementation_check_interface(self, connection, object_path,
+                                                 interface_name, &error)) {
+        g_dbus_method_invocation_take_error(invocation, error);
+        return;
+    }
+    if (!g_dbus_interface_info_lookup_method(self->priv->ifaceinfo,
+                                             method_name)) {
+        g_dbus_method_invocation_return_error(
+            invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD,
+            "Unknown method %s on %s", method_name, interface_name);
+        return;
+    }
 
     g_signal_emit(self, signals[SIGNAL_HANDLE_METHOD], 0, method_name, parameters, invocation);
     g_object_unref (invocation);
@@ -59,6 +113,12 @@ static GVariant* gjs_dbus_implementation_property_get(
     GjsDBusImplementation *self = GJS_DBUS_IMPLEMENTATION (user_data);
     GVariant *value;
 
+    if (!gjs_dbus_implementation_check_interface(self, connection, object_path,
+                                                 interface_name, error) ||
+        !gjs_dbus_implementation_check_property(self, interface_name,
+                                                property_name, error))
+        return NULL;
+
     g_signal_emit(self, signals[SIGNAL_HANDLE_PROPERTY_GET], 0, property_name, &value);
 
     /* Marshaling GErrors is not supported, so this is the best we can do
@@ -76,6 +136,12 @@ static gboolean gjs_dbus_implementation_property_set(
     void* user_data) {
     GjsDBusImplementation *self = GJS_DBUS_IMPLEMENTATION (user_data);
 
+    if (!gjs_dbus_implementation_check_interface(self, connection, object_path,
+                                                 interface_name, error) ||
+        !gjs_dbus_implementation_check_property(self, interface_name,
+                                                property_name, error))
+        return FALSE;
+
     g_signal_emit(self, signals[SIGNAL_HANDLE_PROPERTY_SET], 0, property_name, value);
 
     return TRUE;


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