[glib] gfile: Plug memory leak in g_file_make_directory_with_parents()



commit 5a57144d5749efaf3b5e752db9b041597d4b062f
Author: Colin Walters <walters verbum org>
Date:   Fri May 4 10:03:12 2012 -0400

    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 files 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) 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]