X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=lib%2Fdatabase.cc;h=eaf526677f789a6939ae86adc3b530327289dcf0;hp=563580f1cd117a10b059a9018de3e01cb381fc35;hb=6e9fdf0abf050647da53349943a12f53af692e99;hpb=9b1c6c250b2413b987ffeccbf1cd69cb1e8b934d diff --git a/lib/database.cc b/lib/database.cc index 563580f1..eaf52667 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -55,13 +55,10 @@ typedef struct { * * Multiple terms of given prefix: * - * ref: All unresolved message IDs from In-Reply-To and - * References headers in the message. (Once a referenced - * message is added to the database and the thread IDs - * are linked the corresponding "ref" term is dropped - * from the message document.) + * reference: All message IDs from In-Reply-To and Re ferences + * headers in the message. * - * tag: Any tags associated with this message by the user. + * tag: Any tags associated with this message by the user. * * A mail document also has two values: * @@ -104,7 +101,7 @@ typedef struct { prefix_t BOOLEAN_PREFIX_INTERNAL[] = { { "type", "T" }, - { "ref", "XREFERENCE" }, + { "reference", "XREFERENCE" }, { "replyto", "XREPLYTO" }, { "timestamp", "XTIMESTAMP" }, }; @@ -371,9 +368,16 @@ _parse_message_id (void *ctx, const char *message_id, const char **next) } /* Parse a References header value, putting a (talloc'ed under 'ctx') - * copy of each referenced message-id into 'hash'. */ + * copy of each referenced message-id into 'hash'. + * + * We explicitly avoid including any reference identical to + * 'message_id' in the result (to avoid mass confusion when a single + * message references itself cyclically---and yes, mail messages are + * not infrequent in the wild that do this---don't ask me why). +*/ static void parse_references (void *ctx, + const char *message_id, GHashTable *hash, const char *refs) { @@ -385,7 +389,7 @@ parse_references (void *ctx, while (*refs) { ref = _parse_message_id (ctx, refs, &refs); - if (ref) + if (ref && strcmp (ref, message_id)) g_hash_table_insert (hash, ref, NULL); } } @@ -697,7 +701,7 @@ _notmuch_database_link_message_to_parents (notmuch_database_t *notmuch, const char **thread_id) { GHashTable *parents = NULL; - const char *refs, *in_reply_to; + const char *refs, *in_reply_to, *in_reply_to_message_id; GList *l, *keys = NULL; notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS; @@ -705,12 +709,21 @@ _notmuch_database_link_message_to_parents (notmuch_database_t *notmuch, _my_talloc_free_for_g_hash, NULL); refs = notmuch_message_file_get_header (message_file, "references"); - parse_references (message, parents, refs); + parse_references (message, notmuch_message_get_message_id (message), + parents, refs); in_reply_to = notmuch_message_file_get_header (message_file, "in-reply-to"); - parse_references (message, parents, in_reply_to); - _notmuch_message_add_term (message, "replyto", - _parse_message_id (message, in_reply_to, NULL)); + parse_references (message, notmuch_message_get_message_id (message), + parents, in_reply_to); + + /* Carefully avoid adding any self-referential in-reply-to term. */ + in_reply_to_message_id = _parse_message_id (message, in_reply_to, NULL); + if (strcmp (in_reply_to_message_id, + notmuch_message_get_message_id (message))) + { + _notmuch_message_add_term (message, "replyto", + _parse_message_id (message, in_reply_to, NULL)); + } keys = g_hash_table_get_keys (parents); for (l = keys; l; l = l->next) { @@ -723,7 +736,8 @@ _notmuch_database_link_message_to_parents (notmuch_database_t *notmuch, parent_message_id); if (parent_thread_id == NULL) { - _notmuch_message_add_term (message, "ref", parent_message_id); + _notmuch_message_add_term (message, "reference", + parent_message_id); } else { if (*thread_id == NULL) { *thread_id = talloc_strdup (message, parent_thread_id); @@ -757,7 +771,7 @@ _notmuch_database_link_message_to_children (notmuch_database_t *notmuch, notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS; notmuch_private_status_t private_status; - find_doc_ids (notmuch, "ref", message_id, &child, &children_end); + find_doc_ids (notmuch, "reference", message_id, &child, &children_end); for ( ; child != children_end; child++) { @@ -774,7 +788,7 @@ _notmuch_database_link_message_to_children (notmuch_database_t *notmuch, *thread_id = talloc_strdup (message, child_thread_id); _notmuch_message_add_term (message, "thread", *thread_id); } else if (strcmp (*thread_id, child_thread_id)) { - _notmuch_message_remove_term (child_message, "ref", + _notmuch_message_remove_term (child_message, "reference", message_id); _notmuch_message_sync (child_message); ret = _merge_threads (notmuch, *thread_id, child_thread_id); @@ -796,7 +810,7 @@ _notmuch_database_link_message_to_children (notmuch_database_t *notmuch, /* Given a (mostly empty) 'message' and its corresponding * 'message_file' link it to existing threads in the database. * - * We first looke at 'message_file' and its link-relevant headers + * We first look at 'message_file' and its link-relevant headers * (References and In-Reply-To) for message IDs. We also look in the * database for existing message that reference 'message'.p * @@ -911,9 +925,7 @@ notmuch_database_add_message (notmuch_database_t *notmuch, * (which may or may not reference an existing document in the * database). */ - /* Use NULL for owner since we want to free this locally. */ - message = _notmuch_message_create_for_message_id (NULL, - notmuch, + message = _notmuch_message_create_for_message_id (notmuch, message_id, &private_status);