From ab61fbccbd29973d11ade9c9349a054ec00a4eda Mon Sep 17 00:00:00 2001 From: Bertrand Lorentz Date: Sun, 18 Nov 2012 16:06:34 +0100 Subject: [PATCH] glib: Fix crash when freeing lists with elements typed as interfaces If a GList or a GSList had its element type set to a GInterface, and if the elements were marked as owned, it would end up freeing those elements with g_free(), which would lead to a crash. They need to be unreffed with g_object_unref, but the criteria for that was whether the element type is assignable to GLib.Object. This is not true for GInterface types. We now first check if the element type is an opaque. If not, and if it's assignable to GLib.IWrapper, we then use g_object_unref. From what I can see, all GLib.IWrapper subclasses that not opaque can be unreffed with g_object_unref. --- glib/ListBase.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/glib/ListBase.cs b/glib/ListBase.cs index d5360a347..3077b80b9 100644 --- a/glib/ListBase.cs +++ b/glib/ListBase.cs @@ -188,14 +188,17 @@ namespace GLib { public void Empty () { - if (elements_owned) - for (uint i = 0; i < Count; i++) - if (typeof (GLib.Object).IsAssignableFrom (element_type)) - g_object_unref (NthData (i)); - else if (typeof (GLib.Opaque).IsAssignableFrom (element_type)) + if (elements_owned) { + for (uint i = 0; i < Count; i++) { + if (typeof (GLib.Opaque).IsAssignableFrom (element_type)) { GLib.Opaque.GetOpaque (NthData (i), element_type, true).Dispose (); - else + } else if (typeof (GLib.IWrapper).IsAssignableFrom (element_type)) { + g_object_unref (NthData (i)); + } else { g_free (NthData (i)); + } + } + } if (managed) FreeList ();