summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert McQueen <robot101@debian.org>2006-04-28 21:02:16 +0000
committerRobert McQueen <robot101@debian.org>2006-04-28 21:02:16 +0000
commitb3f18b3040663fb2dd631985d5a9010ba3a31265 (patch)
tree3dc0b797c20714cb468708eb070e8afa394b70d4
parent6055e1cf44ffc03a1e338c0aa45ef22d1dd7ad1c (diff)
2005-04-28 Robert McQueen <robot101@debian.org>
* glib/dbus-gvalue-utils.c: Patch from Jakub Stachowski to fix leaking of memory from within pointer arrays and lists. Fixes bug #6300.
-rw-r--r--ChangeLog5
-rw-r--r--glib/dbus-gvalue-utils.c62
2 files changed, 61 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index fdb65cf1..f79c400a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2005-04-28 Robert McQueen <robot101@debian.org>
+ * glib/dbus-gvalue-utils.c: Patch from Jakub Stachowski to fix leaking
+ of memory from within pointer arrays and lists. Fixes bug #6300.
+
+2005-04-28 Robert McQueen <robot101@debian.org>
+
* glib/dbus-gvalue.c: Patch from Jakub Stachowski to fix a leak in
generating struct signatures. Fixes bug #6083.
diff --git a/glib/dbus-gvalue-utils.c b/glib/dbus-gvalue-utils.c
index f64a921f..39b4cd9b 100644
--- a/glib/dbus-gvalue-utils.c
+++ b/glib/dbus-gvalue-utils.c
@@ -772,6 +772,31 @@ gvalue_from_ptrarray_value (GValue *value, gpointer instance)
}
}
+static void
+gvalue_take_from_ptrarray_value (GValue *value, gpointer instance)
+{
+ switch (g_type_fundamental (G_VALUE_TYPE (value)))
+ {
+ case G_TYPE_STRING:
+ g_value_take_string (value, instance);
+ break;
+ case G_TYPE_POINTER:
+ g_value_set_pointer (value, instance);
+ g_assert_not_reached ();
+ break;
+ case G_TYPE_BOXED:
+ g_value_take_boxed (value, instance);
+ break;
+ case G_TYPE_OBJECT:
+ g_value_take_object (value, instance);
+ g_object_unref (g_value_get_object (value));
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+}
+
static gpointer
ptrarray_value_from_gvalue (const GValue *value)
{
@@ -796,7 +821,7 @@ ptrarray_value_from_gvalue (const GValue *value)
}
static void
-ptrarray_iterator (GType hash_type,
+ptrarray_iterator (GType ptrarray_type,
gpointer instance,
DBusGTypeSpecializedCollectionIterator iterator,
gpointer user_data)
@@ -807,7 +832,7 @@ ptrarray_iterator (GType hash_type,
ptrarray = instance;
- elt_gtype = dbus_g_type_get_collection_specialization (hash_type);
+ elt_gtype = dbus_g_type_get_collection_specialization (ptrarray_type);
for (i = 0; i < ptrarray->len; i++)
{
@@ -822,8 +847,8 @@ static void
ptrarray_copy_elt (const GValue *val, gpointer user_data)
{
GPtrArray *dest = user_data;
- GValue val_copy = {0, };
-
+ GValue val_copy = {0, };
+
g_value_init (&val_copy, G_VALUE_TYPE (val));
g_value_copy (val, &val_copy);
@@ -858,9 +883,22 @@ ptrarray_append (DBusGTypeSpecializedAppendContext *ctx, GValue *value)
static void
ptrarray_free (GType type, gpointer val)
{
- /* XXX: this function appears to leak the contents of the array */
GPtrArray *array;
+ GValue elt_val = {0, };
+ GType elt_gtype;
+ unsigned int i;
+
array = val;
+
+ elt_gtype = dbus_g_type_get_collection_specialization (type);
+
+ for (i = 0; i < array->len; i++)
+ {
+ g_value_init (&elt_val, elt_gtype);
+ gvalue_take_from_ptrarray_value (&elt_val, g_ptr_array_index (array, i));
+ g_value_unset (&elt_val);
+ }
+
g_ptr_array_free (array, TRUE);
}
@@ -943,9 +981,21 @@ slist_end_append (DBusGTypeSpecializedAppendContext *ctx)
static void
slist_free (GType type, gpointer val)
{
- /* XXX: this function appears to leak the contents of the list */
GSList *list;
+ GType elt_gtype;
list = val;
+
+ elt_gtype = dbus_g_type_get_collection_specialization (type);
+
+ while (list != NULL)
+ {
+ GValue elt_val = {0, };
+ g_value_init (&elt_val, elt_gtype);
+ gvalue_take_from_ptrarray_value (&elt_val, list->data);
+ g_value_unset (&elt_val);
+ list = g_slist_next(list);
+ }
+ list=val;
g_slist_free (list);
}