desktop-data-model r7277 - trunk/engine-dbus



Author: otaylor
Date: Wed Apr 23 17:36:23 2008
New Revision: 7277
URL: http://svn.gnome.org/viewvc/desktop-data-model?rev=7277&view=rev

Log:
Take care to never try to send a NULL client_id over the BUS, even
 if we get bad data back from the server.


Modified:
   trunk/engine-dbus/hippo-dbus-model-client.c

Modified: trunk/engine-dbus/hippo-dbus-model-client.c
==============================================================================
--- trunk/engine-dbus/hippo-dbus-model-client.c	(original)
+++ trunk/engine-dbus/hippo-dbus-model-client.c	Wed Apr 23 17:36:23 2008
@@ -119,12 +119,12 @@
 
 /*****************************************************************/
 
-static void
-add_property_value_to_message(DBusMessageIter    *property_array_iter,
-                              DDMQName           *property_qname,
-                              DDMDataUpdate       update,
-                              DDMDataValue       *value,
-                              DDMDataCardinality  cardinality)
+static gboolean
+add_property_value_to_message(DBusMessageIter      *property_array_iter,
+                              DDMQName             *property_qname,
+                              DDMDataUpdate         update,
+                              DDMDataValue         *value,
+                              DDMDataCardinality    cardinality)
 {
     DBusMessageIter property_iter;
     DBusMessageIter value_iter;
@@ -132,7 +132,16 @@
     char type_byte;
     char cardinality_byte;
     const char *value_signature = NULL;
-    
+
+    /* Avoid sending pointers to resources we don't know anything about
+     * about to clients.
+     */
+    if (value->type == DDM_DATA_RESOURCE) {
+        const char *class_id = ddm_data_resource_get_resource_id(value->u.resource);
+        if (class_id == NULL)
+            return FALSE;
+    }
+        
     switch (update) {
     case DDM_DATA_UPDATE_ADD:
         update_byte = 'a';
@@ -247,9 +256,11 @@
     
     dbus_message_iter_close_container(&property_iter, &value_iter);
     dbus_message_iter_close_container(property_array_iter, &property_iter);
+
+    return TRUE;
 }
 
-static void
+static gboolean
 add_feed_property_value_to_message(DBusMessageIter    *property_array_iter,
                                    DDMQName           *property_qname,
                                    DDMDataUpdate       update,
@@ -264,7 +275,14 @@
     char cardinality_byte;
     const char *value_signature = NULL;
     const char *item_resource_id = ddm_data_resource_get_resource_id(item_resource);
+    const char *item_class_id = ddm_data_resource_get_class_id(item_resource);
     
+    /* Avoid sending pointers to resources we don't know anything about
+     * about to clients.
+     */
+    if (item_class_id == NULL)
+        return FALSE;
+        
     switch (update) {
     case DDM_DATA_UPDATE_ADD:
         update_byte = 'a';
@@ -300,6 +318,8 @@
     
     dbus_message_iter_close_container(&property_iter, &value_iter);
     dbus_message_iter_close_container(property_array_iter, &property_iter);
+
+    return TRUE;
 }
 
 static void
@@ -364,15 +384,30 @@
                                       &value, cardinality);
     } else if (DDM_DATA_IS_LIST(value.type)) {
         GSList *l;
+        gboolean seen_one = FALSE;
         
         for (l = value.u.list; l; l = l->next) {
             DDMDataValue element;
             ddm_data_value_get_element(&value, l, &element);
             
+            if (add_property_value_to_message(property_array_iter, property_qname,
+                                              l == value.u.list ? DDM_DATA_UPDATE_REPLACE : DDM_DATA_UPDATE_ADD,
+                                              &element, cardinality))
+                seen_one = TRUE;
+        }
+
+        /* If all the values in a resource-valued list were invalid (NULL class_id,
+         * we have to send a CLEAR indication to signal an empty list.
+         */
+        if (!seen_one) {
+            DDMDataValue tmp;
+            
+            tmp.type = DDM_DATA_NONE;
             add_property_value_to_message(property_array_iter, property_qname,
-                                          l == value.u.list ? DDM_DATA_UPDATE_REPLACE : DDM_DATA_UPDATE_ADD,
-                                          &element, cardinality);
+                                          DDM_DATA_UPDATE_CLEAR,
+                                          &tmp, cardinality);
         }
+        
     } else if (value.type == DDM_DATA_FEED) {
         if (value.u.feed != NULL) {
             DDMFeedIter feed_iter;
@@ -401,6 +436,13 @@
                 first = FALSE;
             }
         }
+
+        /* We really should send an empty-feed indication over the BUS if we didnt'
+         * send any items, as we do for items, but we don't have a convenient way of
+         * doing that at the moment; this will become less important when we
+         * add client-side expectations for type/cardinality to the Python bindings
+         * in any case.
+         */
     } else {
         add_property_value_to_message(property_array_iter, property_qname,
                                       DDM_DATA_UPDATE_REPLACE,
@@ -428,6 +470,15 @@
     gboolean direct_notification;
     dbus_bool_t indirect_bool;
 
+    /* A null class_id means that something went wrong with the fetch. (We got
+     * a reference to an object from upstream, but didn't get the object.)
+     * If we send a NULL string via D-BUS, we'll crash, so just omit the resource.
+     */
+    resource_id = ddm_data_resource_get_resource_id(resource);
+    class_id = ddm_data_resource_get_class_id(resource);
+    if (class_id == NULL)
+        g_warning("Skipping object with null class_id; resource_id=%s", resource_id);
+
     connection = g_hash_table_lookup(client->connections, ddm_data_resource_get_resource_id(resource));
     if (connection == NULL) {
         connection = data_client_connection_new(client, resource);
@@ -482,8 +533,6 @@
         ddm_data_fetch_iter_clear(&fetch_iter);
     }
     
-    resource_id = ddm_data_resource_get_resource_id(resource);
-    class_id = ddm_data_resource_get_class_id(resource);
     indirect_bool = indirect;
 
     dbus_message_iter_open_container(resource_array_iter, DBUS_TYPE_STRUCT, NULL, &resource_iter);



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