[gjs] Fix memory leaks



commit 90b7edc968565c932a59033a6a9790f776d63d4c
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Sat Jun 16 16:36:18 2012 +0200

    Fix memory leaks
    
    GValues inside flat arrays must be unset when not transferring
    ownership, and GErrors must be freed after setting the exception.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=669350

 gi/arg.c               |   32 ++++++++++++++++++++++++++++++--
 gjs/jsapi-util-error.c |    1 +
 2 files changed, 31 insertions(+), 2 deletions(-)
---
diff --git a/gi/arg.c b/gi/arg.c
index 3f82d9c..2d57627 100644
--- a/gi/arg.c
+++ b/gi/arg.c
@@ -2795,7 +2795,10 @@ gjs_g_arg_release_internal(JSContext  *context,
                 g_closure_unref(arg->v_pointer);
             } else if (g_type_is_a(gtype, G_TYPE_VALUE)) {
                 /* G_TYPE_VALUE is-a G_TYPE_BOXED, but we special case it */
-                g_boxed_free(gtype, arg->v_pointer);
+                if (g_type_info_is_pointer (type_info))
+                    g_boxed_free(gtype, arg->v_pointer);
+                else
+                    g_value_unset (arg->v_pointer);
             } else if (g_type_is_a(gtype, G_TYPE_BOXED)) {
                 if (transfer != TRANSFER_IN_NOTHING)
                     g_boxed_free(gtype, arg->v_pointer);
@@ -2860,7 +2863,25 @@ gjs_g_arg_release_internal(JSContext  *context,
             param_info = g_type_info_get_param_type(type_info, 0);
             element_type = g_type_info_get_tag(param_info);
 
-            if (transfer != GI_TRANSFER_CONTAINER && is_gvalue_flat_array(param_info, element_type)) {
+            if (is_gvalue_flat_array(param_info, element_type)) {
+                if (transfer != GI_TRANSFER_CONTAINER) {
+                    gint len = g_type_info_get_array_fixed_size(type_info);
+                    gint i;
+
+                    if (len < 0) {
+                        gjs_throw(context,
+                                  "Releasing a flat GValue array that was not fixed-size or was nested"
+                                  "inside another container. This is not supported (and will leak)");
+                        g_base_info_unref(param_info);
+                        return JS_FALSE;
+                    }
+
+                    for (i = 0; i < len; i++) {
+                        GValue *v = ((GValue*)arg->v_pointer) + i;
+                        g_value_unset(v);
+                    }
+                }
+
                 g_free(arg->v_pointer);
                 g_base_info_unref(param_info);
                 return JS_TRUE;
@@ -3170,6 +3191,13 @@ gjs_g_argument_release_in_array (JSContext  *context,
     param_type = g_type_info_get_param_type(type_info, 0);
     type_tag = g_type_info_get_tag(param_type);
 
+    if (is_gvalue_flat_array(param_type, type_tag)) {
+        for (i = 0; i < length; i++) {
+            GValue *v = ((GValue*)array) + i;
+            g_value_unset(v);
+        }
+    }
+
     if (type_needs_release(param_type, type_tag)) {
         for (i = 0; i < length; i++) {
             elem.v_pointer = array[i];
diff --git a/gjs/jsapi-util-error.c b/gjs/jsapi-util-error.c
index 88ac97e..8227fe1 100644
--- a/gjs/jsapi-util-error.c
+++ b/gjs/jsapi-util-error.c
@@ -162,6 +162,7 @@ gjs_throw_g_error (JSContext       *context,
     JS_BeginRequest(context);
 
     err_obj = gjs_error_from_gerror(context, error, TRUE);
+    g_error_free (error);
     if (err_obj)
         JS_SetPendingException(context, OBJECT_TO_JSVAL(err_obj));
 



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