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
This commit is contained in:
Colin Walters 2012-05-04 10:03:12 -04:00
parent d5d3c7b3a4
commit 5a57144d57

View File

@ -3400,7 +3400,7 @@ g_file_make_directory_with_parents (GFile *file,
GError **error) GError **error)
{ {
gboolean result; gboolean result;
GFile *parent_file, *work_file; GFile *work_file = NULL;
GList *list = NULL, *l; GList *list = NULL, *l;
GError *my_error = NULL; GError *my_error = NULL;
@ -3415,27 +3415,36 @@ g_file_make_directory_with_parents (GFile *file,
return result; return result;
} }
work_file = file; work_file = g_object_ref (file);
while (!result && my_error->code == G_IO_ERROR_NOT_FOUND) while (!result && my_error->code == G_IO_ERROR_NOT_FOUND)
{ {
GFile *parent_file;
g_clear_error (&my_error); g_clear_error (&my_error);
parent_file = g_file_get_parent (work_file); parent_file = g_file_get_parent (work_file);
if (parent_file == NULL) if (parent_file == NULL)
break; break;
result = g_file_make_directory (parent_file, cancellable, &my_error); 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) for (l = list; result && l; l = l->next)
{ {
result = g_file_make_directory ((GFile *) l->data, cancellable, &my_error); result = g_file_make_directory ((GFile *) l->data, cancellable, &my_error);
} }
if (work_file)
g_object_unref (work_file);
/* Clean up */ /* Clean up */
while (list != NULL) while (list != NULL)