dbus/glib dbus-gvalue-utils.c,1.13,1.14

Rob McQueen robot101 at kemper.freedesktop.org
Tue Jun 6 17:03:59 PDT 2006


Update of /cvs/dbus/dbus/glib
In directory kemper:/tmp/cvs-serv14676/glib

Modified Files:
	dbus-gvalue-utils.c 
Log Message:
2005-05-06  Robert McQueen  <robot101 at debian.org>

	* glib/dbus-gvalue-utils.c: Fix the failing test where static string
	  pointers were put into a GPtrArray-based specialised collection, and
	  then freed along with the array. GValues which you add into
	  collections or maps which have the NOCOPY flag set are assumed to not
	  belong to the caller, so rather than the existing pointer-stealing
	  semantics, they are copied instead. Given that the main consumers of
	  this abstraction are the bindings themselves, I don't think this is
	  too bad, but others should watch their choice of take vs set_static.

Index: dbus-gvalue-utils.c
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gvalue-utils.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- dbus-gvalue-utils.c	6 Jun 2006 23:07:04 -0000	1.13
+++ dbus-gvalue-utils.c	7 Jun 2006 00:03:57 -0000	1.14
@@ -744,6 +744,20 @@
 static gpointer
 ptrarray_value_from_gvalue (const GValue *value)
 {
+  GValue tmp = {0, };
+
+  /* if the NOCOPY flag is set, then value was created via set_static and hence
+   * is not owned by us. in order to preserve the "take" semantics that the API
+   * has in general (which avoids copying in the common case), we must copy any
+   * static values so that we can indiscriminately free the entire collection
+   * later. */
+  if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
+    {
+      g_value_init (&tmp, G_VALUE_TYPE (value));
+      g_value_copy (value, &tmp);
+      value = &tmp;
+    }
+
   switch (g_type_fundamental (G_VALUE_TYPE (value)))
     {
     case G_TYPE_STRING:
@@ -1315,17 +1329,7 @@
     g_assert (!strcmp ("bar", g_ptr_array_index (instance, 1)));
     g_assert (!strcmp ("baz", g_ptr_array_index (instance, 2)));
 
-    /* FIXME this crashes, I believe because ptrarray_append
-     * doesn't copy the incoming static string, then ptrarray_free
-     * tries to free it; looks to me like always copying appended
-     * values would be the only working approach.
-     */
     g_value_unset (&val);
-    /* FIXME make sure this test fails for everyone, since
-     * apparently people didn't see it, the bad free
-     * maybe didn't crash everywhere
-     */
-    g_assert_not_reached();
   }
 
   type = dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_UINT, DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);



More information about the dbus-commit mailing list