From: Michael Gruenewald Date: Fri, 2 Feb 2018 14:39:56 +0000 (+0100) Subject: Prevent double-replacements in mentions X-Git-Tag: v0.9~68 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=f4631c02433fdaaa699b1896ce38cacc48d4580d;p=pidgin-chime.git Prevent double-replacements in mentions Outgoing mentions replace a name with a reference to the Chime user. Sometimes you have two users with the same name in a chat room, or two people where one name is a prefix of another one. This could end up with something like `<@id1|<@id2|Last, First>>`, which is broken. This change makes sure to only replace at word borders and not if a `|` is in front. This isn't perfect, but better than before. --- diff --git a/chat.c b/chat.c index 8b1b96d..ded11de 100644 --- a/chat.c +++ b/chat.c @@ -75,13 +75,13 @@ static int parse_inbound_mentions(ChimeConnection *cxn, GRegex *mention_regex, c strstr(message, "<@present|"); } -static void replace(gchar **dst, const gchar *a, const gchar *b) +static void replace(gchar **dst, const gchar *pattern, const gchar *replacement) { - gchar **parts = g_strsplit(*dst, a, 0); - gchar *replaced = g_strjoinv(b, parts); - g_strfreev(parts); - g_free(*dst); - *dst = replaced; + GRegex *regex = g_regex_new(pattern, 0, 0, NULL); + gchar* replaced = g_regex_replace_literal(regex, *dst, -1, 0, replacement, 0, NULL); + g_regex_unref(regex); + g_free(*dst); + *dst = replaced; } /* @@ -102,8 +102,12 @@ static gchar *parse_outbound_mentions(ChimeRoom *room, const gchar *message) const gchar *display_name = chime_contact_get_display_name(member->contact); if (strstr(parsed, display_name)) { + gchar *display_name_escaped = g_regex_escape_string(display_name, -1); + gchar *search = g_strdup_printf("(?", id, display_name); - replace(&parsed, display_name, chime_mention); + replace(&parsed, search, chime_mention); + g_free(search); g_free(chime_mention); }