From bf88eee1318eb4c47c31ad1b32f515bb6c5d37f2 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 8 Mar 2010 23:56:43 -0500 Subject: [PATCH] Fix file chooser refcounting issues This was reported in bug 600992. --- gtk/gtkfilechooserbutton.c | 21 +++++++++++++-------- gtk/gtkfilechooserdefault.c | 22 ++++++++++++++-------- gtk/gtkfilesystem.c | 24 +++++++++++++++++++++++- gtk/gtkfilesystem.h | 3 ++- gtk/gtkpathbar.c | 2 +- 5 files changed, 53 insertions(+), 19 deletions(-) diff --git a/gtk/gtkfilechooserbutton.c b/gtk/gtkfilechooserbutton.c index 441c15b697..b7227a0bec 100644 --- a/gtk/gtkfilechooserbutton.c +++ b/gtk/gtkfilechooserbutton.c @@ -1586,7 +1586,7 @@ model_free_row_data (GtkFileChooserButton *button, g_object_unref (data); break; case ROW_TYPE_VOLUME: - _gtk_file_system_volume_free (data); + _gtk_file_system_volume_unref (data); break; default: break; @@ -1777,11 +1777,16 @@ model_add_volumes (GtkFileChooserButton *button, GFile *base_file; base_file = _gtk_file_system_volume_get_root (volume); - if (base_file != NULL && !g_file_is_native (base_file)) - { - _gtk_file_system_volume_free (volume); - continue; - } + if (base_file != NULL) + { + if (!g_file_is_native (base_file)) + { + g_object_unref (base_file); + continue; + } + else + g_object_unref (base_file); + } } } @@ -1796,7 +1801,7 @@ model_add_volumes (GtkFileChooserButton *button, ICON_COLUMN, pixbuf, DISPLAY_NAME_COLUMN, display_name, TYPE_COLUMN, ROW_TYPE_VOLUME, - DATA_COLUMN, volume, + DATA_COLUMN, _gtk_file_system_volume_ref (volume), IS_FOLDER_COLUMN, TRUE, -1); @@ -2334,7 +2339,7 @@ update_label_and_image (GtkFileChooserButton *button) if (base_file) g_object_unref (base_file); - _gtk_file_system_volume_free (volume); + _gtk_file_system_volume_unref (volume); if (label_text) goto out; diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c index eefe49c56d..81150d07ec 100644 --- a/gtk/gtkfilechooserdefault.c +++ b/gtk/gtkfilechooserdefault.c @@ -762,14 +762,12 @@ shortcuts_free_row_data (GtkFileChooserDefault *impl, GtkFileSystemVolume *volume; volume = col_data; - _gtk_file_system_volume_free (volume); + _gtk_file_system_volume_unref (volume); } - else + if (shortcut_type == SHORTCUT_TYPE_FILE) { GFile *file; - g_assert (shortcut_type == SHORTCUT_TYPE_FILE); - file = col_data; g_object_unref (file); } @@ -2015,7 +2013,14 @@ shortcuts_add_volumes (GtkFileChooserDefault *impl) } } - shortcuts_insert_file (impl, start_row + n, SHORTCUT_TYPE_VOLUME, volume, NULL, NULL, FALSE, SHORTCUTS_VOLUMES); + shortcuts_insert_file (impl, + start_row + n, + SHORTCUT_TYPE_VOLUME, + _gtk_file_system_volume_ref (volume), + NULL, + NULL, + FALSE, + SHORTCUTS_VOLUMES); n++; } @@ -3437,9 +3442,7 @@ shortcuts_query_tooltip_cb (GtkWidget *widget, if (shortcut_type == SHORTCUT_TYPE_SEPARATOR) return FALSE; else if (shortcut_type == SHORTCUT_TYPE_VOLUME) - { - return FALSE; - } + return FALSE; else if (shortcut_type == SHORTCUT_TYPE_FILE) { GFile *file; @@ -9770,6 +9773,9 @@ shortcuts_activate_mount_enclosing_volume (GCancellable *cancellable, _gtk_file_system_get_info (data->impl->file_system, data->file, "standard::type", shortcuts_activate_get_info_cb, data); + + if (volume) + _gtk_file_system_volume_unref (volume); } static void diff --git a/gtk/gtkfilesystem.c b/gtk/gtkfilesystem.c index bc6cbf588d..ea79fed044 100644 --- a/gtk/gtkfilesystem.c +++ b/gtk/gtkfilesystem.c @@ -468,6 +468,8 @@ get_volumes_list (GtkFileSystem *file_system) priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (drive)); } + + g_object_unref (drive); } g_list_free (drives); @@ -499,6 +501,8 @@ get_volumes_list (GtkFileSystem *file_system) /* see comment above in why we add an icon for a volume */ priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (volume)); } + + g_object_unref (volume); } /* add mounts that has no volume (/etc/mtab mounts, ftp, sftp,...) */ @@ -520,11 +524,13 @@ get_volumes_list (GtkFileSystem *file_system) */ if (mount_referenced_by_volume_activation_root (volumes, mount)) { + g_object_unref (mount); continue; } /* show this mount */ priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (mount)); + g_object_unref (mount); } g_list_free (volumes); @@ -1025,6 +1031,8 @@ enclosing_volume_mount_cb (GObject *source_object, if (error) g_error_free (error); + + _gtk_file_system_volume_unref (volume); } GCancellable * @@ -1802,8 +1810,22 @@ _gtk_file_system_volume_render_icon (GtkFileSystemVolume *volume, return pixbuf; } +GtkFileSystemVolume * +_gtk_file_system_volume_ref (GtkFileSystemVolume *volume) +{ + if (IS_ROOT_VOLUME (volume)) + return volume; + + if (G_IS_MOUNT (volume) || + G_IS_VOLUME (volume) || + G_IS_DRIVE (volume)) + g_object_ref (volume); + + return volume; +} + void -_gtk_file_system_volume_free (GtkFileSystemVolume *volume) +_gtk_file_system_volume_unref (GtkFileSystemVolume *volume) { /* Root volume doesn't need to be freed */ if (IS_ROOT_VOLUME (volume)) diff --git a/gtk/gtkfilesystem.h b/gtk/gtkfilesystem.h index 58f1b4191f..a92c8f89e9 100644 --- a/gtk/gtkfilesystem.h +++ b/gtk/gtkfilesystem.h @@ -162,7 +162,8 @@ GdkPixbuf * _gtk_file_system_volume_render_icon (GtkFileSystemVol gint icon_size, GError **error); -void _gtk_file_system_volume_free (GtkFileSystemVolume *volume); +GtkFileSystemVolume *_gtk_file_system_volume_ref (GtkFileSystemVolume *volume); +void _gtk_file_system_volume_unref (GtkFileSystemVolume *volume); /* GtkFileSystemBookmark methods */ void _gtk_file_system_bookmark_free (GtkFileSystemBookmark *bookmark); diff --git a/gtk/gtkpathbar.c b/gtk/gtkpathbar.c index 48eec632d2..87bec1adfc 100644 --- a/gtk/gtkpathbar.c +++ b/gtk/gtkpathbar.c @@ -1261,7 +1261,7 @@ set_button_image (GtkPathBar *path_bar, GTK_WIDGET (path_bar), path_bar->icon_size, NULL); - _gtk_file_system_volume_free (volume); + _gtk_file_system_volume_unref (volume); gtk_image_set_from_pixbuf (GTK_IMAGE (button_data->image), path_bar->root_icon); break;