From 5a57144d5749efaf3b5e752db9b041597d4b062f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 4 May 2012 10:03:12 -0400 Subject: [PATCH] gfile: Plug memory leak in g_file_make_directory_with_parents() The logic here is pretty twisted, but basically we were leaking a ref for each non-existent parent. The clearest way to fix this was to move to more explicit refcounting logic; when a variable is pointing to an object, it holds a ref. https://bugzilla.gnome.org/show_bug.cgi?id=675446 --- gio/gfile.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/gio/gfile.c b/gio/gfile.c index 52f9add..ba3c95e 100644 --- a/gio/gfile.c +++ b/gio/gfile.c @@ -3400,7 +3400,7 @@ g_file_make_directory_with_parents (GFile *file, GError **error) { gboolean result; - GFile *parent_file, *work_file; + GFile *work_file = NULL; GList *list = NULL, *l; GError *my_error = NULL; @@ -3415,27 +3415,36 @@ g_file_make_directory_with_parents (GFile *file, return result; } - work_file = file; + work_file = g_object_ref (file); while (!result && my_error->code == G_IO_ERROR_NOT_FOUND) { + GFile *parent_file; + g_clear_error (&my_error); - + parent_file = g_file_get_parent (work_file); if (parent_file == NULL) break; result = g_file_make_directory (parent_file, cancellable, &my_error); - - if (!result && my_error->code == G_IO_ERROR_NOT_FOUND) - list = g_list_prepend (list, parent_file); - work_file = parent_file; + g_object_unref (work_file); + work_file = g_object_ref (parent_file); + + if (!result && my_error->code == G_IO_ERROR_NOT_FOUND) + list = g_list_prepend (list, parent_file); /* Transfer ownership of ref */ + else + g_object_unref (parent_file); } + g_clear_error (&my_error); for (l = list; result && l; l = l->next) { result = g_file_make_directory ((GFile *) l->data, cancellable, &my_error); } + + if (work_file) + g_object_unref (work_file); /* Clean up */ while (list != NULL) -- 2.7.4