diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2018-09-09 00:00:47 +0200 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2018-09-09 13:24:07 +0200 |
commit | 3b7ed345c276aada49a2f95279eb6ac496ebc530 (patch) | |
tree | 147ef046d6580a3901dc9441785afce57b1f73f0 | |
parent | dbc3445c40a9caafc1e3b4e8ce4665b1cfcdb861 (diff) | |
download | tracker-3b7ed345c276aada49a2f95279eb6ac496ebc530.tar.gz |
libtracker-miner: Fix lookup of already interned files
This code had several wrongs here:
- The tracker_file_system_is_file_interned got the check_fs
parameter wrong, creating an additional copy of the file.
This would be inocuous as the later lookup would succeed,
except
- The extra copy of the file was being leaked
- And actually the later lookup is somewhat superfluous if
we are checking the NodeLookupData. We can shortcircuit
lookup of files already interned in this TrackerFileSystem
even further.
This all is fixed now, the tracker_file_system_is_file_interned()
function got open coded in the caller function so we can perform
the fast path, the check has been corrected, and even if we would
fall through the paths that do need a copy, it wouldn't be leaked.
-rw-r--r-- | src/libtracker-miner/tracker-file-system.c | 31 |
1 files changed, 13 insertions, 18 deletions
diff --git a/src/libtracker-miner/tracker-file-system.c b/src/libtracker-miner/tracker-file-system.c index 961da4714..e21bded18 100644 --- a/src/libtracker-miner/tracker-file-system.c +++ b/src/libtracker-miner/tracker-file-system.c @@ -529,22 +529,6 @@ file_system_get_node (TrackerFileSystem *file_system, return file_tree_lookup (priv->file_tree, file, NULL, NULL); } -static gboolean -tracker_file_system_is_file_interned (TrackerFileSystem *file_system, - GFile *file, - gboolean check_fs) -{ - NodeLookupData *lookup_data; - - lookup_data = g_object_get_qdata (G_OBJECT (file), quark_file_node); - if (!lookup_data) - return FALSE; - if (check_fs && lookup_data->file_system != file_system) - return FALSE; - - return TRUE; -} - GFile * tracker_file_system_get_file (TrackerFileSystem *file_system, GFile *file, @@ -552,23 +536,30 @@ tracker_file_system_get_file (TrackerFileSystem *file_system, GFile *parent) { TrackerFileSystemPrivate *priv; + NodeLookupData *lookup_data; FileNodeData *data; GNode *node, *parent_node, *lookup_node = NULL; gchar *uri_prefix = NULL; + GFile *copy = NULL; g_return_val_if_fail (G_IS_FILE (file), NULL); g_return_val_if_fail (TRACKER_IS_FILE_SYSTEM (file_system), NULL); priv = file_system->priv; node = NULL; + lookup_data = g_object_get_qdata (G_OBJECT (file), quark_file_node); /* If file is interned somewhere else, get a separate copy of the * file for this filesystem. */ - if (tracker_file_system_is_file_interned (file_system, file, FALSE)) { + if (lookup_data && lookup_data->file_system != file_system) { gchar *uri = g_file_get_uri (file); - file = g_file_new_for_uri (uri); + copy = g_file_new_for_uri (uri); g_free (uri); + file = copy; + } else if (lookup_data) { + /* Short circuit path, file is already interned */ + return file; } if (parent) { @@ -593,6 +584,8 @@ tracker_file_system_get_file (TrackerFileSystem *file_system, g_warning ("NOTE: URI theme may be outside scheme expected, for example, expecting 'file://' when given 'http://' prefix."); g_free (uri); + g_clear_object (©); + return NULL; } @@ -612,6 +605,8 @@ tracker_file_system_get_file (TrackerFileSystem *file_system, } } + g_clear_object (©); + return data->file; } |