mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-28 13:12:10 +01:00
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:
parent
d5d3c7b3a4
commit
5a57144d57
23
gio/gfile.c
23
gio/gfile.c
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user