summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiovanni Campagna <gcampagna@src.gnome.org>2012-06-16 16:36:18 +0200
committerGiovanni Campagna <gcampagna@src.gnome.org>2012-08-07 21:34:20 +0200
commit90b7edc968565c932a59033a6a9790f776d63d4c (patch)
treeb85d798064a9a156a4007331245b2b6c3c6c602c
parent0e7f255f16c04dc737b45fe1fb68893bdde643b1 (diff)
downloadgjs-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.c32
-rw-r--r--gjs/jsapi-util-error.c1
2 files changed, 31 insertions, 2 deletions
diff --git a/gi/arg.c b/gi/arg.c
index 3f82d9c5..2d576277 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 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));