=?utf-8?q?=5Bperl-Glib-Object-Introspection=5D_Plug_a_leak_in_SV_?= =?utf-8?b?4oaSIEdMaXN0IGFuZCBTViDihpIgR1NMaXN0?=



commit e488930914957547883cdc30da58c32ff9238665
Author: Torsten SchÃnfeld <kaffeetisch gmx de>
Date:   Sat Jul 7 21:11:32 2012 +0200

    Plug a leak in SV â GList and SV â GSList

 GObjectIntrospection.xs   |    2 +-
 gperl-i11n-marshal-arg.c  |    2 +-
 gperl-i11n-marshal-list.c |   38 ++++++++++++++++++++++++--------------
 3 files changed, 26 insertions(+), 16 deletions(-)
---
diff --git a/GObjectIntrospection.xs b/GObjectIntrospection.xs
index 158d988..d1794f7 100644
--- a/GObjectIntrospection.xs
+++ b/GObjectIntrospection.xs
@@ -236,7 +236,7 @@ static SV * array_to_sv (GITypeInfo *info, gpointer pointer, GITransfer transfer
 static gpointer sv_to_array (GITransfer transfer, GITypeInfo *type_info, SV *sv, GPerlI11nInvocationInfo *iinfo);
 
 static SV * glist_to_sv (GITypeInfo* info, gpointer pointer, GITransfer transfer);
-static gpointer sv_to_glist (GITransfer transfer, GITypeInfo * type_info, SV * sv);
+static gpointer sv_to_glist (GITransfer transfer, GITypeInfo * type_info, SV * sv, GPerlI11nInvocationInfo *iinfo);
 
 static SV * ghash_to_sv (GITypeInfo *info, gpointer pointer, GITransfer transfer);
 static gpointer sv_to_ghash (GITransfer transfer, GITypeInfo *type_info, SV *sv);
diff --git a/gperl-i11n-marshal-arg.c b/gperl-i11n-marshal-arg.c
index 0d1bd38..b24f547 100644
--- a/gperl-i11n-marshal-arg.c
+++ b/gperl-i11n-marshal-arg.c
@@ -99,7 +99,7 @@ sv_to_arg (SV * sv,
 
 	    case GI_TYPE_TAG_GLIST:
 	    case GI_TYPE_TAG_GSLIST:
-		arg->v_pointer = sv_to_glist (transfer, type_info, sv);
+		arg->v_pointer = sv_to_glist (transfer, type_info, sv, invocation_info);
 		break;
 
 	    case GI_TYPE_TAG_GHASH:
diff --git a/gperl-i11n-marshal-list.c b/gperl-i11n-marshal-list.c
index 416d603..c674239 100644
--- a/gperl-i11n-marshal-list.c
+++ b/gperl-i11n-marshal-list.c
@@ -1,5 +1,19 @@
 /* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; -*- */
 
+static void
+free_list (GList *list)
+{
+	dwarn ("free_list %p\n", list);
+	g_list_free (list);
+}
+
+static void
+free_slist (GSList *list)
+{
+	dwarn ("free_slist %p\n", list);
+	g_slist_free (list);
+}
+
 /* This may call Perl code (via arg_to_sv), so it needs to be wrapped with
  * PUTBACK/SPAGAIN by the caller. */
 static SV *
@@ -21,7 +35,7 @@ glist_to_sv (GITypeInfo* info,
 	/* FIXME: What about an array containing arrays of strings, where the
 	 * outer array is GI_TRANSFER_EVERYTHING but the inner arrays are
 	 * GI_TRANSFER_CONTAINER? */
-	item_transfer = transfer == GI_TRANSFER_EVERYTHING
+	item_transfer = GI_TRANSFER_EVERYTHING == transfer
 		? GI_TRANSFER_EVERYTHING
 		: GI_TRANSFER_NOTHING;
 
@@ -57,7 +71,7 @@ glist_to_sv (GITypeInfo* info,
 }
 
 static gpointer
-sv_to_glist (GITransfer transfer, GITypeInfo * type_info, SV * sv)
+sv_to_glist (GITransfer transfer, GITypeInfo * type_info, SV * sv, GPerlI11nInvocationInfo *iinfo)
 {
 	AV *av;
 	GITransfer item_transfer;
@@ -75,18 +89,9 @@ sv_to_glist (GITransfer transfer, GITypeInfo * type_info, SV * sv)
 		ccroak ("need an array ref to convert to GList");
 	av = (AV *) SvRV (sv);
 
-	item_transfer = GI_TRANSFER_NOTHING;
-	switch (transfer) {
-	    case GI_TRANSFER_EVERYTHING:
-		item_transfer = GI_TRANSFER_EVERYTHING;
-		break;
-	    case GI_TRANSFER_CONTAINER:
-		/* nothing special to do */
-		break;
-	    case GI_TRANSFER_NOTHING:
-		/* FIXME: need to free list after call */
-		break;
-	}
+	item_transfer = GI_TRANSFER_EVERYTHING == transfer
+		? GI_TRANSFER_EVERYTHING
+		: GI_TRANSFER_NOTHING;
 
 	param_info = g_type_info_get_param_type (type_info, 0);
 	dwarn ("  G(S)List: param_info %p with type tag %d (%s) and transfer %d\n",
@@ -116,6 +121,11 @@ sv_to_glist (GITransfer transfer, GITypeInfo * type_info, SV * sv)
 		}
 	}
 
+	if (GI_TRANSFER_NOTHING == transfer)
+		free_after_call (iinfo,
+		                 is_slist ? ((GFunc)free_slist) : ((GFunc)free_list),
+		                 list);
+
 	dwarn ("    -> list %p of length %d\n", list, g_list_length (list));
 
 	g_base_info_unref ((GIBaseInfo *) param_info);



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