Blob Blame History Raw
From 9b05b2cbc7e859371b3cc36b493ea88284a23c85 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Wed, 7 Aug 2019 14:39:08 +0200
Subject: [PATCH] libtracker-miner: Ensure basename utf8-ness in filters

Filenames with invalid UTF-8 may cause invalid writes on
g_pattern_match(), as patterns like '*a*a' will require the reverse of
the string, and g_utf8_strreverse() might write past boundaries if
the invalid UTF-8 happens near the end of the given string. See
https://gitlab.gnome.org/GNOME/glib/issues/1863.

Ensure the UTF-8-ness of the string by replacing those invalid characters,
they presumably are irrelevant for matching purposes (as the patterns
express valid UTF-8). Also reverse the string in place, so it's slightly
faster at checking all the patterns.

This seems a frequent crash report in Fedora FAF along time, eg:
https://retrace.fedoraproject.org/faf/reports/2559134/
https://retrace.fedoraproject.org/faf/reports/1598399/
---
 src/libtracker-miner/tracker-indexing-tree.c | 23 ++++++++++++++------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/src/libtracker-miner/tracker-indexing-tree.c b/src/libtracker-miner/tracker-indexing-tree.c
index 53007931c..dfbba4562 100644
--- a/src/libtracker-miner/tracker-indexing-tree.c
+++ b/src/libtracker-miner/tracker-indexing-tree.c
@@ -748,7 +748,9 @@ tracker_indexing_tree_file_matches_filter (TrackerIndexingTree *tree,
 {
 	TrackerIndexingTreePrivate *priv;
 	GList *filters;
-	gchar *basename;
+	gchar *basename, *str, *reverse;
+	gboolean match = FALSE;
+	gint len;
 
 	g_return_val_if_fail (TRACKER_IS_INDEXING_TREE (tree), FALSE);
 	g_return_val_if_fail (G_IS_FILE (file), FALSE);
@@ -757,6 +759,10 @@ tracker_indexing_tree_file_matches_filter (TrackerIndexingTree *tree,
 	filters = priv->filter_patterns;
 	basename = g_file_get_basename (file);
 
+	str = g_utf8_make_valid (basename, -1);
+	len = strlen (str);
+	reverse = g_utf8_strreverse (str, len);
+
 	while (filters) {
 		PatternData *data = filters->data;
 
@@ -768,18 +774,21 @@ tracker_indexing_tree_file_matches_filter (TrackerIndexingTree *tree,
 		if (data->file &&
 		    (g_file_equal (file, data->file) ||
 		     g_file_has_prefix (file, data->file))) {
-			g_free (basename);
-			return TRUE;
+			match = TRUE;
+			break;
 		}
 
-		if (g_pattern_match_string (data->pattern, basename)) {
-			g_free (basename);
-			return TRUE;
+		if (g_pattern_match (data->pattern, len, str, reverse)) {
+			match = TRUE;
+			break;
 		}
 	}
 
 	g_free (basename);
-	return FALSE;
+	g_free (str);
+	g_free (reverse);
+
+	return match;
 }
 
 static gboolean
-- 
2.23.0.rc1