From a91fa644d5ac6f9de420bd2fe441797b0321e3b2 Mon Sep 17 00:00:00 2001 From: djcb Date: Tue, 7 Aug 2012 11:43:54 +0300 Subject: [PATCH] * lib: correctly handle embedded text parts --- lib/mu-msg-file.c | 2 ++ lib/mu-msg-part.c | 29 +++++++++++++++++++---------- lib/mu-msg-priv.h | 6 +++++- lib/mu-store-write.cc | 6 ++++-- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/lib/mu-msg-file.c b/lib/mu-msg-file.c index 7225bf88..c42e2d59 100644 --- a/lib/mu-msg-file.c +++ b/lib/mu-msg-file.c @@ -521,6 +521,8 @@ mu_msg_mime_part_to_string (GMimePart *part, gboolean *err) buffer = NULL; stream = NULL; + g_return_val_if_fail (err, NULL); + *err = TRUE; /* guilty until proven innocent */ g_return_val_if_fail (GMIME_IS_PART(part), NULL); diff --git a/lib/mu-msg-part.c b/lib/mu-msg-part.c index 451ec4d2..fb80d3ea 100644 --- a/lib/mu-msg-part.c +++ b/lib/mu-msg-part.c @@ -35,8 +35,8 @@ #endif /*BUILD_CRYPTO*/ static gboolean handle_children (MuMsg *msg, GMimeObject *mobj, MuMsgOptions opts, - unsigned index, MuMsgPartForeachFunc func, gpointer user_data); - + unsigned index, MuMsgPartForeachFunc func, + gpointer user_data); struct _DoData { GMimeObject *mime_obj; @@ -137,7 +137,7 @@ accumulate_text (MuMsg *msg, MuMsgPart *part, GString **gstrp) if (!g_mime_content_type_is_type (ctype, "text", "plain")) return; /* not plain text */ txt = mu_msg_mime_part_to_string - ((GMimePart*)part, &err); + ((GMimePart*)part->data, &err); if (txt) g_string_append (*gstrp, txt); g_free (txt); @@ -153,6 +153,8 @@ mu_msg_part_get_text (MuMsg *msg, MuMsgPart *self, MuMsgOptions opts, g_return_val_if_fail (msg, NULL); g_return_val_if_fail (self && self->data, NULL); + g_return_val_if_fail (err, NULL); + mobj = (GMimeObject*)self->data; if (GMIME_IS_PART (mobj) && @@ -363,8 +365,13 @@ handle_encrypted_part (MuMsg *msg, } static gboolean -looks_like_body (GMimeObject *parent, MuMsgPart *msgpart) +looks_like_body (MuMsg *msg, GMimeObject *parent, MuMsgPart *msgpart) { + /* if we've already seen a body for this one, don't consider + * more */ + if (msg->_file->_body_seen) + return FALSE; + if (parent && !GMIME_IS_MESSAGE_PART(parent) && !GMIME_IS_MULTIPART(parent)) @@ -399,8 +406,11 @@ handle_part (MuMsg *msg, GMimePart *part, GMimeObject *parent, msgpart.part_type |= get_disposition ((GMimeObject*)part); /* a top-level non-attachment text part is probably a body */ - if (looks_like_body (parent, &msgpart)) + if (looks_like_body (msg, parent, &msgpart)) { msgpart.part_type |= MU_MSG_PART_TYPE_BODY; + /* remember that we (probably) saw the body */ + msg->_file->_body_seen = TRUE; + } msgpart.data = (gpointer)part; msgpart.index = index; @@ -434,12 +444,11 @@ handle_message_part (MuMsg *msg, GMimeMessagePart *mmsg, GMimeObject *parent, func (msg, &msgpart, user_data); if (opts & MU_MSG_OPTION_RECURSE_RFC822) { - GMimeMessage *mime_msg; - mime_msg = g_mime_message_part_get_message (mmsg); + GMimeObject *mobj; + mobj = g_mime_message_get_mime_part + (g_mime_message_part_get_message (mmsg)); return handle_children - (msg, - (GMimeObject*)mime_msg, - opts, index, func, user_data); + (msg, mobj, opts, index, func, user_data); } return TRUE; } diff --git a/lib/mu-msg-priv.h b/lib/mu-msg-priv.h index b5496279..f55cea2a 100644 --- a/lib/mu-msg-priv.h +++ b/lib/mu-msg-priv.h @@ -44,6 +44,10 @@ struct _MuMsgFile { char _path [PATH_MAX + 1]; char _maildir [PATH_MAX + 1]; + /* when we iterate over the parts, remember whether + * the body has been seen already */ + gboolean _body_seen; + /* list where we push allocated strings so we can * free them when the struct gets destroyed */ @@ -69,7 +73,7 @@ struct _MuMsg { * convert a GMimePart to a string * * @param part a GMimePart - * @param err will receive TRUE if there was an error, FALSE otherwise + * @param err will receive TRUE if there was an error, FALSE otherwise. Must NOT be NULL. * * @return utf8 string for this MIME part, to be freed by caller */ diff --git a/lib/mu-store-write.cc b/lib/mu-store-write.cc index 513b188b..2629636c 100644 --- a/lib/mu-store-write.cc +++ b/lib/mu-store-write.cc @@ -390,6 +390,8 @@ maybe_index_text_part (MuMsg *msg, MuMsgPart *part, PartData *pdata) char *txt, *norm; Xapian::TermGenerator termgen; + /* we handle the body text elsewhere; this is about other text + * parts */ if (part->part_type & MU_MSG_PART_TYPE_BODY) return; @@ -458,7 +460,7 @@ add_terms_values_attach (Xapian::Document& doc, MuMsg *msg, MuMsgFieldId mfid, GStringChunk *strchunk) { PartData pdata (doc, mfid, strchunk); - mu_msg_part_foreach (msg, MU_MSG_OPTION_NONE, + mu_msg_part_foreach (msg, MU_MSG_OPTION_RECURSE_RFC822, (MuMsgPartForeachFunc)each_part, &pdata); } @@ -688,7 +690,7 @@ mu_store_add_msg (MuStore *store, MuMsg *msg, GError **err) doc.add_term (term); - MU_WRITE_LOG ("adding: %s", term.c_str()); + // MU_WRITE_LOG ("adding: %s", term.c_str()); /* note, this will replace any other messages for this path */ id = store->db_writable()->replace_document (term, doc);