diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2021-02-04 22:29:24 +0100 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2021-02-04 22:38:07 +0100 |
commit | c843defcbb5c6bcce7d17843b2fbd53b55831faf (patch) | |
tree | 0ec98dd61c2a43fb81b92cbf06f53ee99826dac6 | |
parent | d1feb4b76e16e4b61dc296b7e7131d5357af0596 (diff) | |
download | tracker-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.c | 25 |
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); } |