* lib: correctly handle embedded text parts

This commit is contained in:
djcb
2012-08-07 11:43:54 +03:00
parent ea67fcf0e8
commit a91fa644d5
4 changed files with 30 additions and 13 deletions

View File

@ -521,6 +521,8 @@ mu_msg_mime_part_to_string (GMimePart *part, gboolean *err)
buffer = NULL; buffer = NULL;
stream = NULL; stream = NULL;
g_return_val_if_fail (err, NULL);
*err = TRUE; /* guilty until proven innocent */ *err = TRUE; /* guilty until proven innocent */
g_return_val_if_fail (GMIME_IS_PART(part), NULL); g_return_val_if_fail (GMIME_IS_PART(part), NULL);

View File

@ -35,8 +35,8 @@
#endif /*BUILD_CRYPTO*/ #endif /*BUILD_CRYPTO*/
static gboolean handle_children (MuMsg *msg, GMimeObject *mobj, MuMsgOptions opts, 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 { struct _DoData {
GMimeObject *mime_obj; 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")) if (!g_mime_content_type_is_type (ctype, "text", "plain"))
return; /* not plain text */ return; /* not plain text */
txt = mu_msg_mime_part_to_string txt = mu_msg_mime_part_to_string
((GMimePart*)part, &err); ((GMimePart*)part->data, &err);
if (txt) if (txt)
g_string_append (*gstrp, txt); g_string_append (*gstrp, txt);
g_free (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 (msg, NULL);
g_return_val_if_fail (self && self->data, NULL); g_return_val_if_fail (self && self->data, NULL);
g_return_val_if_fail (err, NULL);
mobj = (GMimeObject*)self->data; mobj = (GMimeObject*)self->data;
if (GMIME_IS_PART (mobj) && if (GMIME_IS_PART (mobj) &&
@ -363,8 +365,13 @@ handle_encrypted_part (MuMsg *msg,
} }
static gboolean 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 && if (parent &&
!GMIME_IS_MESSAGE_PART(parent) && !GMIME_IS_MESSAGE_PART(parent) &&
!GMIME_IS_MULTIPART(parent)) !GMIME_IS_MULTIPART(parent))
@ -399,8 +406,11 @@ handle_part (MuMsg *msg, GMimePart *part, GMimeObject *parent,
msgpart.part_type |= get_disposition ((GMimeObject*)part); msgpart.part_type |= get_disposition ((GMimeObject*)part);
/* a top-level non-attachment text part is probably a body */ /* 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; 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.data = (gpointer)part;
msgpart.index = index; msgpart.index = index;
@ -434,12 +444,11 @@ handle_message_part (MuMsg *msg, GMimeMessagePart *mmsg, GMimeObject *parent,
func (msg, &msgpart, user_data); func (msg, &msgpart, user_data);
if (opts & MU_MSG_OPTION_RECURSE_RFC822) { if (opts & MU_MSG_OPTION_RECURSE_RFC822) {
GMimeMessage *mime_msg; GMimeObject *mobj;
mime_msg = g_mime_message_part_get_message (mmsg); mobj = g_mime_message_get_mime_part
(g_mime_message_part_get_message (mmsg));
return handle_children return handle_children
(msg, (msg, mobj, opts, index, func, user_data);
(GMimeObject*)mime_msg,
opts, index, func, user_data);
} }
return TRUE; return TRUE;
} }

View File

@ -44,6 +44,10 @@ struct _MuMsgFile {
char _path [PATH_MAX + 1]; char _path [PATH_MAX + 1];
char _maildir [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 /* list where we push allocated strings so we can
* free them when the struct gets destroyed * free them when the struct gets destroyed
*/ */
@ -69,7 +73,7 @@ struct _MuMsg {
* convert a GMimePart to a string * convert a GMimePart to a string
* *
* @param part a GMimePart * @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 * @return utf8 string for this MIME part, to be freed by caller
*/ */

View File

@ -390,6 +390,8 @@ maybe_index_text_part (MuMsg *msg, MuMsgPart *part, PartData *pdata)
char *txt, *norm; char *txt, *norm;
Xapian::TermGenerator termgen; Xapian::TermGenerator termgen;
/* we handle the body text elsewhere; this is about other text
* parts */
if (part->part_type & MU_MSG_PART_TYPE_BODY) if (part->part_type & MU_MSG_PART_TYPE_BODY)
return; return;
@ -458,7 +460,7 @@ add_terms_values_attach (Xapian::Document& doc, MuMsg *msg,
MuMsgFieldId mfid, GStringChunk *strchunk) MuMsgFieldId mfid, GStringChunk *strchunk)
{ {
PartData pdata (doc, mfid, 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); (MuMsgPartForeachFunc)each_part, &pdata);
} }
@ -688,7 +690,7 @@ mu_store_add_msg (MuStore *store, MuMsg *msg, GError **err)
doc.add_term (term); 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 */ /* note, this will replace any other messages for this path */
id = store->db_writable()->replace_document (term, doc); id = store->db_writable()->replace_document (term, doc);