From a03635ee68f043b68c1bb4cb95114af3ecb65ec4 Mon Sep 17 00:00:00 2001 From: Ondrej Holy Date: Fri, 14 Nov 2014 10:08:03 +0100 Subject: metadata: don't crash if meta_tree_init fails It can fail when e.g. database file is corrupted or doesn't have correct permissions. This patch also adds warnings to be possible determine reason why initialization failed. It is based on patches from Matthew W. S. Bell and Ross Lagerwall. https://bugzilla.gnome.org/show_bug.cgi?id=598561 --- client/gdaemonfile.c | 22 +++++++-- client/gdaemonvfs.c | 135 ++++++++++++++++++++++++++++----------------------- 2 files changed, 90 insertions(+), 67 deletions(-) (limited to 'client') diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c index e97c9a4e..53e5f9a0 100644 --- a/client/gdaemonfile.c +++ b/client/gdaemonfile.c @@ -830,12 +830,16 @@ add_metadata (GFile *file, tree = meta_tree_lookup_by_name (treename, FALSE); g_free (treename); - g_file_info_set_attribute_mask (info, matcher); - meta_tree_enumerate_keys (tree, daemon_file->path, - enumerate_keys_callback, info); - g_file_info_unset_attribute_mask (info); + if (tree) + { + g_file_info_set_attribute_mask (info, matcher); + meta_tree_enumerate_keys (tree, daemon_file->path, + enumerate_keys_callback, info); + g_file_info_unset_attribute_mask (info); + + meta_tree_unref (tree); + } - meta_tree_unref (tree); g_file_attribute_matcher_unref (matcher); } @@ -2649,6 +2653,14 @@ set_metadata_attribute (GFile *file, tree = meta_tree_lookup_by_name (treename, FALSE); g_free (treename); + if (!tree) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Error setting file metadata: %s"), + _("can't open metadata tree")); + return FALSE; + } + res = FALSE; proxy = _g_daemon_vfs_get_metadata_proxy (cancellable, error); diff --git a/client/gdaemonvfs.c b/client/gdaemonvfs.c index 9ab806b3..1060c440 100644 --- a/client/gdaemonvfs.c +++ b/client/gdaemonvfs.c @@ -1,3 +1,4 @@ + /* GIO - GLib Input, Output and Streaming Library * * Copyright (C) 2006-2007 Red Hat, Inc. @@ -1279,69 +1280,79 @@ g_daemon_vfs_local_file_set_attributes (GVfs *vfs, statbuf.st_dev, FALSE, &tree_path); - - proxy = _g_daemon_vfs_get_metadata_proxy (NULL, error); - if (proxy == NULL) - { - res = FALSE; + if (!tree) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Error setting file metadata: %s"), + _("can't open metadata tree")); + res = FALSE; error = NULL; /* Don't set further errors */ - } - else - { - builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); - metatreefile = meta_tree_get_filename (tree); - num_set = 0; - - for (i = 0; attributes[i] != NULL; i++) - { - if (g_file_info_get_attribute_data (info, attributes[i], &type, &value, NULL)) - { - appended = _g_daemon_vfs_append_metadata_for_set (builder, - tree, - tree_path, - attributes[i], - type, - value); - if (appended != -1) - { - num_set += appended; - g_file_info_set_attribute_status (info, attributes[i], - G_FILE_ATTRIBUTE_STATUS_SET); - } - else - { - res = FALSE; - g_set_error (error, G_IO_ERROR, - G_IO_ERROR_INVALID_ARGUMENT, - _("Error setting file metadata: %s"), - _("values must be string or list of strings")); - error = NULL; /* Don't set further errors */ - g_file_info_set_attribute_status (info, attributes[i], - G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING); - } - } - } - - if (num_set > 0 && - ! gvfs_metadata_call_set_sync (proxy, - metatreefile, - tree_path, - g_variant_builder_end (builder), - NULL, - error)) - { - res = FALSE; - error = NULL; /* Don't set further errors */ - for (i = 0; attributes[i] != NULL; i++) - g_file_info_set_attribute_status (info, attributes[i], - G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING); - } - - g_variant_builder_unref (builder); - - meta_lookup_cache_free (cache); - meta_tree_unref (tree); - g_free (tree_path); + } + else + { + proxy = _g_daemon_vfs_get_metadata_proxy (NULL, error); + if (proxy == NULL) + { + res = FALSE; + error = NULL; /* Don't set further errors */ + } + else + { + builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); + metatreefile = meta_tree_get_filename (tree); + num_set = 0; + + for (i = 0; attributes[i] != NULL; i++) + { + if (g_file_info_get_attribute_data (info, attributes[i], &type, &value, NULL)) + { + appended = _g_daemon_vfs_append_metadata_for_set (builder, + tree, + tree_path, + attributes[i], + type, + value); + if (appended != -1) + { + num_set += appended; + g_file_info_set_attribute_status (info, attributes[i], + G_FILE_ATTRIBUTE_STATUS_SET); + } + else + { + res = FALSE; + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Error setting file metadata: %s"), + _("values must be string or list of strings")); + error = NULL; /* Don't set further errors */ + g_file_info_set_attribute_status (info, attributes[i], + G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING); + } + } + } + + if (num_set > 0 && + ! gvfs_metadata_call_set_sync (proxy, + metatreefile, + tree_path, + g_variant_builder_end (builder), + NULL, + error)) + { + res = FALSE; + error = NULL; /* Don't set further errors */ + for (i = 0; attributes[i] != NULL; i++) + g_file_info_set_attribute_status (info, attributes[i], + G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING); + } + + g_variant_builder_unref (builder); + + meta_lookup_cache_free (cache); + meta_tree_unref (tree); + g_free (tree_path); + } } } -- cgit v1.2.1