summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2021-02-04 22:29:24 +0100
committerCarlos Garnacho <carlosg@gnome.org>2021-02-04 22:38:07 +0100
commitc843defcbb5c6bcce7d17843b2fbd53b55831faf (patch)
tree0ec98dd61c2a43fb81b92cbf06f53ee99826dac6
parentd1feb4b76e16e4b61dc296b7e7131d5357af0596 (diff)
downloadtracker-c843defcbb5c6bcce7d17843b2fbd53b55831faf.tar.gz
libtracker-common: Improve terminal ellipsizing helper
This was in a sorry state for some reasons: - It was pretty oblivious to UTF-8, so it might cut the string mid-character. - It uses g_memdup(), which should be best avoided. See https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1928 For the former, use g_utf8_* API to count characters (which is what we want for terminal formatting purposes). For the latter, use g_strndup(), which is gchar* oriented and takes gsize, to avoid vulnerabilities and incompatibilities.
-rw-r--r--src/libtracker-common/tracker-term-utils.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/src/libtracker-common/tracker-term-utils.c b/src/libtracker-common/tracker-term-utils.c
index 96e90da5f..d619d209d 100644
--- a/src/libtracker-common/tracker-term-utils.c
+++ b/src/libtracker-common/tracker-term-utils.c
@@ -39,18 +39,37 @@ tracker_term_ellipsize (const gchar *str,
gint max_len,
TrackerEllipsizeMode mode)
{
- gint len = strlen (str);
+ gsize size = strlen (str);
+ glong len = g_utf8_strlen (str, size);
+ const gchar *begin, *end, *pos;
gchar *substr, *retval;
+ gint i;
if (len < max_len)
return g_strdup (str);
+ /* Account for the ellipsizing char */
+ max_len--;
+ if (max_len <= 0)
+ return g_strdup ("…");
+
+ begin = str;
+ end = &str[size];
+
if (mode == TRACKER_ELLIPSIZE_START) {
- substr = g_memdup (str + len - max_len + 1, max_len - 1);
+ pos = begin;
+ for (i = 0; i < max_len; i++)
+ pos = g_utf8_find_next_char (pos, end);
+
+ substr = g_strndup (begin, pos - begin);
retval = g_strdup_printf ("…%s", substr);
g_free (substr);
} else {
- substr = g_memdup (str, max_len - 1);
+ pos = end;
+ for (i = 0; i < max_len; i++)
+ pos = g_utf8_find_prev_char (begin, pos);
+
+ substr = g_strndup (pos, end - pos);
retval = g_strdup_printf ("%s…", substr);
g_free (substr);
}