From 61f66966ddfe8ebd8bae26dd7ff92d777004edda Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Tue, 12 Nov 2019 14:47:57 +0100 Subject: [PATCH] Check for correct delay tag for muc timestamps https://github.com/profanity-im/profanity/issues/1190 had another issue: Sometimes servers send multiple and we just checked the first one we got and only used it if the 'from' attribute was fitting. However it could be that we actually wanted the second element and there the 'from' would have been right. So we need to loop through them until we get the one with the fitting 'from'. Fix https://github.com/profanity-im/profanity/issues/1190 --- src/xmpp/message.c | 13 +++++++------ src/xmpp/stanza.c | 46 ++++++++++++++++++++++++++++++++++------------ src/xmpp/stanza.h | 2 +- 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/xmpp/message.c b/src/xmpp/message.c index d1808ba5..b6f7f5c7 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -831,16 +831,17 @@ _handle_groupchat(xmpp_stanza_t *const stanza) } // determine if the notifications happened whilst offline - gchar *from; - message->timestamp = stanza_get_delay_from(stanza, &from); - // checking the domainpart is a workaround for some prosody versions (gh#1190) - if (message->timestamp && (g_strcmp0(jid->barejid, from) == 0 - || g_strcmp0(jid->domainpart, from) == 0)) { + message->timestamp = stanza_get_delay_from(stanza, jid->barejid); + if (message->timestamp == NULL) { + // checking the domainpart is a workaround for some prosody versions (gh#1190) + message->timestamp = stanza_get_delay_from(stanza, jid->domainpart); + } + + if (message->timestamp) { sv_ev_room_history(message); } else { sv_ev_room_message(message); } - g_free(from); out: message_free(message); diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index bb7e9092..bead38d4 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -1171,6 +1171,24 @@ stanza_create_caps_sha1_from_query(xmpp_stanza_t *const query) return result; } +xmpp_stanza_t* +stanza_get_child_by_name_and_from(xmpp_stanza_t * const stanza, const char * const name, const char * const from) +{ + xmpp_stanza_t *child; + const char *child_from; + + for (child = xmpp_stanza_get_children(stanza); child; child = xmpp_stanza_get_next(child)) { + if (strcmp(name, xmpp_stanza_get_name(child)) == 0) { + child_from = xmpp_stanza_get_attribute(child, STANZA_ATTR_FROM); + if (child_from && strcmp(from, child_from) == 0) { + break; + } + } + } + + return child; +} + GDateTime* stanza_get_delay(xmpp_stanza_t *const stanza) { @@ -1178,11 +1196,18 @@ stanza_get_delay(xmpp_stanza_t *const stanza) } GDateTime* -stanza_get_delay_from(xmpp_stanza_t *const stanza, gchar **from) +stanza_get_delay_from(xmpp_stanza_t *const stanza, gchar *from) { GTimeVal utc_stamp; // first check for XEP-0203 delayed delivery - xmpp_stanza_t *delay = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_DELAY); + xmpp_stanza_t *delay; + + if (from) { + delay = stanza_get_child_by_name_and_from(stanza, STANZA_NAME_DELAY, from); + } else { + delay = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_DELAY); + } + if (delay) { const char *xmlns = xmpp_stanza_get_attribute(delay, STANZA_ATTR_XMLNS); if (xmlns && (strcmp(xmlns, "urn:xmpp:delay") == 0)) { @@ -1191,9 +1216,6 @@ stanza_get_delay_from(xmpp_stanza_t *const stanza, gchar **from) GDateTime *utc_datetime = g_date_time_new_from_timeval_utc(&utc_stamp); GDateTime *local_datetime = g_date_time_to_local(utc_datetime); g_date_time_unref(utc_datetime); - if (from) { - *from = g_strdup(xmpp_stanza_get_attribute(delay, STANZA_ATTR_FROM)); - } return local_datetime; } } @@ -1201,7 +1223,13 @@ stanza_get_delay_from(xmpp_stanza_t *const stanza, gchar **from) // otherwise check for XEP-0091 legacy delayed delivery // stanp format : CCYYMMDDThh:mm:ss - xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X); + xmpp_stanza_t *x; + if (from) { + x = stanza_get_child_by_name_and_from(stanza, STANZA_NAME_X, from); + } else { + x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X); + } + if (x) { const char *xmlns = xmpp_stanza_get_attribute(x, STANZA_ATTR_XMLNS); if (xmlns && (strcmp(xmlns, "jabber:x:delay") == 0)) { @@ -1210,17 +1238,11 @@ stanza_get_delay_from(xmpp_stanza_t *const stanza, gchar **from) GDateTime *utc_datetime = g_date_time_new_from_timeval_utc(&utc_stamp); GDateTime *local_datetime = g_date_time_to_local(utc_datetime); g_date_time_unref(utc_datetime); - if (from) { - *from = g_strdup(xmpp_stanza_get_attribute(x, STANZA_ATTR_FROM)); - } return local_datetime; } } } - if (from) { - *from = NULL; - } return NULL; } diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index 0212ed0e..31078ae8 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -267,7 +267,7 @@ xmpp_stanza_t* stanza_create_mediated_invite(xmpp_ctx_t *ctx, const char *const gboolean stanza_contains_chat_state(xmpp_stanza_t *stanza); GDateTime* stanza_get_delay(xmpp_stanza_t *const stanza); -GDateTime* stanza_get_delay_from(xmpp_stanza_t *const stanza, gchar **from); +GDateTime* stanza_get_delay_from(xmpp_stanza_t *const stanza, gchar *from); gboolean stanza_is_muc_presence(xmpp_stanza_t *const stanza); gboolean stanza_is_muc_self_presence(xmpp_stanza_t *const stanza,