about summary refs log tree commit diff stats
path: root/src/xmpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/xmpp')
-rw-r--r--src/xmpp/message.c13
-rw-r--r--src/xmpp/stanza.c46
-rw-r--r--src/xmpp/stanza.h2
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,