diff options
author | Giovanni Campagna <gcampagna@src.gnome.org> | 2012-06-16 16:36:18 +0200 |
---|---|---|
committer | Giovanni Campagna <gcampagna@src.gnome.org> | 2012-08-07 21:34:20 +0200 |
commit | 90b7edc968565c932a59033a6a9790f776d63d4c (patch) | |
tree | b85d798064a9a156a4007331245b2b6c3c6c602c | |
parent | 0e7f255f16c04dc737b45fe1fb68893bdde643b1 (diff) | |
download | gjs-90b7edc968565c932a59033a6a9790f776d63d4c.tar.gz |
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
-rw-r--r-- | gi/arg.c | 32 | ||||
-rw-r--r-- | gjs/jsapi-util-error.c | 1 |
2 files changed, 31 insertions, 2 deletions
@@ -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 88ac97e7..8227fe1d 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)); |