message_get_thread_id: Generate internal error if message has no thread ID.
authorCarl Worth <cworth@cworth.org>
Tue, 17 Nov 2009 19:07:38 +0000 (11:07 -0800)
committerCarl Worth <cworth@cworth.org>
Wed, 18 Nov 2009 01:42:32 +0000 (17:42 -0800)
This case was happening when a message had its own message ID in its
In-Reply-To header. The thread-resolution code would find the
partially constructed message, (with no thread ID yet), get garbage
from this function, and then march right along with that garbage.

With this commit, a self-cyclic message like this will now trigger an
internal error rather than marching along silienty. (And a subsequent
commit will remove the call to this function in this case.)

lib/message.cc

index c3eb2e6ec9b618c77a119423c9ad98730d9c348b..cb9026439b75647486e4e2b3953da53a8b924e2f 100644 (file)
@@ -320,31 +320,39 @@ _notmuch_message_get_in_reply_to (notmuch_message_t *message)
 const char *
 notmuch_message_get_thread_id (notmuch_message_t *message)
 {
+    const char *prefix = _find_prefix ("thread");
     Xapian::TermIterator i;
+    std::string id;
+
+    /* This code is written with the assumption that "thread" has a
+     * single-character prefix. */
+    assert (strlen (prefix) == 1);
 
     if (message->thread_id)
        return message->thread_id;
 
     i = message->doc.termlist_begin ();
-    i.skip_to (_find_prefix ("thread"));
 
-    if (i == message->doc.termlist_end ())
+    i.skip_to (prefix);
+
+    id = *i;
+
+    if (i == message->doc.termlist_end () || id[0] != *prefix)
        INTERNAL_ERROR ("Message with document ID of %d has no thread ID.\n",
                        message->doc_id);
 
-    message->thread_id = talloc_strdup (message, (*i).c_str () + 1);
+    message->thread_id = talloc_strdup (message, id.c_str () + 1);
 
 #if DEBUG_DATABASE_SANITY
     i++;
+    id = *i;
 
-    if (i != message->doc.termlist_end () &&
-       strncmp ((*i).c_str (), _find_prefix ("thread"),
-                strlen (_find_prefix ("thread"))) == 0)
+    if (i != message->doc.termlist_end () && id[0] == *prefix)
     {
        INTERNAL_ERROR ("Message %s has duplicate thread IDs: %s and %s\n",
                        notmuch_message_get_message_id (message),
                        message->thread_id,
-                       (*i).c_str () + 1);
+                       id.c_str () + 1);
     }
 #endif