[telepathy-gabble/telepathy-gabble-0.8] Don't trust <message> ids to be globally unique

Will Thompson will.thompson at collabora.co.uk
Tue Oct 6 06:59:01 PDT 2009


---
 src/im-channel.c                |   25 ++++++++++++-------------
 src/muc-channel.c               |   24 ++++++++++++------------
 tests/twisted/text/test-text.py |   12 +++++++++---
 3 files changed, 33 insertions(+), 28 deletions(-)

diff --git a/src/im-channel.c b/src/im-channel.c
index 57861d8..477a3f5 100644
--- a/src/im-channel.c
+++ b/src/im-channel.c
@@ -530,6 +530,7 @@ _gabble_im_channel_receive (GabbleIMChannel *chan,
   GabbleIMChannelPrivate *priv;
   TpBaseConnection *base_conn;
   TpMessage *msg;
+  gchar *tmp;
 
   g_assert (GABBLE_IS_IM_CHANNEL (chan));
   priv = chan->priv;
@@ -562,9 +563,6 @@ _gabble_im_channel_receive (GabbleIMChannel *chan,
   if (timestamp != 0)
     tp_message_set_uint64 (msg, 0, "message-sent", timestamp);
 
-  if (id != NULL)
-    tp_message_set_string (msg, 0, "message-token", id);
-
   /* Body */
   tp_message_set_string (msg, 1, "content-type", "text/plain");
   tp_message_set_string (msg, 1, "content", text);
@@ -575,22 +573,18 @@ _gabble_im_channel_receive (GabbleIMChannel *chan,
           sender);
       tp_message_set_uint64 (msg, 0, "message-received", time (NULL));
 
-      /* Ensure that all incoming messages have an ID, either from the
-       * protocol or just a locally generated UUID */
-      if (id == NULL)
-        {
-          gchar *tmp = gabble_generate_id ();
-
-          tp_message_set_string (msg, 0, "message-token", tmp);
-          g_free (tmp);
-        }
+      /* We can't trust the id='' attribute set by the contact to be unique
+       * enough to be a message-token, so let's generate one locally.
+       */
+      tmp = gabble_generate_id ();
+      tp_message_set_string (msg, 0, "message-token", tmp);
+      g_free (tmp);
 
       tp_message_mixin_take_received (G_OBJECT (chan), msg);
     }
   else
     {
       TpMessage *delivery_report = tp_message_new (base_conn, 1, 1);
-      gchar *tmp;
 
       tp_message_set_uint32 (delivery_report, 0, "message-type",
           TP_CHANNEL_TEXT_MESSAGE_TYPE_DELIVERY_REPORT);
@@ -614,6 +608,11 @@ _gabble_im_channel_receive (GabbleIMChannel *chan,
        * message must be us! */
       tp_message_set_handle (msg, 0, "message-sender", TP_HANDLE_TYPE_CONTACT,
           base_conn->self_handle);
+
+      /* Since this is a send error, we can trust the id on the message. */
+      if (id != NULL)
+        tp_message_set_string (msg, 0, "message-token", id);
+
       tp_message_take_message (delivery_report, 0, "delivery-echo", msg);
 
       tp_message_mixin_take_received (G_OBJECT (chan), delivery_report);
diff --git a/src/muc-channel.c b/src/muc-channel.c
index cce471b..e91745d 100644
--- a/src/muc-channel.c
+++ b/src/muc-channel.c
@@ -2379,6 +2379,7 @@ _gabble_muc_channel_receive (GabbleMucChannel *chan,
   TpHandle muc_self_handle;
   gboolean is_echo;
   gboolean is_error;
+  gchar *tmp;
 
   g_assert (GABBLE_IS_MUC_CHANNEL (chan));
 
@@ -2428,17 +2429,12 @@ _gabble_muc_channel_receive (GabbleMucChannel *chan,
   if (timestamp != 0)
     tp_message_set_uint64 (message, 0, "message-sent", timestamp);
 
-  if (id != NULL)
-    tp_message_set_string (message, 0, "message-token", id);
-
   /* Body */
   tp_message_set_string (message, 1, "content-type", "text/plain");
   tp_message_set_string (message, 1, "content", text);
 
   if (is_error || is_echo)
     {
-      gchar *tmp;
-
       /* Error reports and echos of our own messages are represented as
        * delivery reports.
        */
@@ -2472,6 +2468,11 @@ _gabble_muc_channel_receive (GabbleMucChannel *chan,
       tp_message_set_handle (message, 0, "message-sender",
           TP_HANDLE_TYPE_CONTACT, muc_self_handle);
 
+      /* If we sent the message whose delivery has succeeded or failed, we
+       * trust the id='' attribute. */
+      if (id != NULL)
+        tp_message_set_string (message, 0, "message-token", id);
+
       tp_message_take_message (delivery_report, 0, "delivery-echo",
           message);
 
@@ -2487,13 +2488,12 @@ _gabble_muc_channel_receive (GabbleMucChannel *chan,
       if (timestamp != 0)
         tp_message_set_boolean (message, 0, "scrollback", TRUE);
 
-      if (id == NULL)
-        {
-          gchar *tmp = gabble_generate_id ();
-
-          tp_message_set_string (message, 0, "message-token", tmp);
-          g_free (tmp);
-        }
+      /* We can't trust the id='' attribute set by the contact to be unique
+       * enough to be a message-token, so let's generate one locally.
+       */
+      tmp = gabble_generate_id ();
+      tp_message_set_string (message, 0, "message-token", tmp);
+      g_free (tmp);
 
       tp_message_mixin_take_received (G_OBJECT (chan), message);
     }
diff --git a/tests/twisted/text/test-text.py b/tests/twisted/text/test-text.py
index 401bf11..e685429 100644
--- a/tests/twisted/text/test-text.py
+++ b/tests/twisted/text/test-text.py
@@ -8,7 +8,7 @@ import dbus
 from twisted.words.xish import domish
 
 from gabbletest import exec_test
-from servicetest import EventPattern, wrap_channel
+from servicetest import EventPattern, wrap_channel, assertNotEquals
 import constants as cs
 
 def test(q, bus, conn, stream):
@@ -16,10 +16,12 @@ def test(q, bus, conn, stream):
     q.expect('dbus-signal', signal='StatusChanged',
             args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED])
 
+    id = '1845a1a9-f7bc-4a2e-a885-633aadc81e1b'
+
     # <message type="chat"><body>hello</body</message>
     m = domish.Element((None, 'message'))
     m['from'] = 'foo at bar.com/Pidgin'
-    m['id'] = '1845a1a9-f7bc-4a2e-a885-633aadc81e1b'
+    m['id'] = id
     m['type'] = 'chat'
     m.addElement('body', content='hello')
     stream.send(m)
@@ -82,7 +84,11 @@ def test(q, bus, conn, stream):
     # the spec says that message-type "MAY be omitted for normal chat
     # messages."
     assert 'message-type' not in header or header['message-type'] == 0, header
-    assert header['message-token'] == '1845a1a9-f7bc-4a2e-a885-633aadc81e1b'
+
+    # This looks wrong, but is correct. We don't know if our contacts generate
+    # message id='' attributes which are unique enough for our requirements, so
+    # we should not use them as the message-token for incoming messages.
+    assertNotEquals(id, header['message-token'])
 
     assert body['content-type'] == 'text/plain', body
     assert body['content'] == 'hello', body
-- 
1.5.6.5



More information about the telepathy-commits mailing list