diff options
author | 2013-09-03 20:33:21 -0700 | |
---|---|---|
committer | 2013-09-03 20:33:21 -0700 | |
commit | 79253cf925c48e3740f28d75ece8c0a319872678 (patch) | |
tree | 2591ffd48b861f47fcf8e36746145c19eb1e45d0 /src/core/rfc822 | |
parent | 325e9353182e49cb87e91ae44ad0fb7452f360d9 (diff) |
Improved Content-Description support and fixed crash (Fixed #350)
Diffstat (limited to 'src/core/rfc822')
-rw-r--r-- | src/core/rfc822/MCAttachment.cc | 379 | ||||
-rw-r--r-- | src/core/rfc822/MCMessageBuilder.cc | 21 |
2 files changed, 208 insertions, 192 deletions
diff --git a/src/core/rfc822/MCAttachment.cc b/src/core/rfc822/MCAttachment.cc index 4d92acba..331d7d28 100644 --- a/src/core/rfc822/MCAttachment.cc +++ b/src/core/rfc822/MCAttachment.cc @@ -104,25 +104,25 @@ String * Attachment::mimeTypeForFilename(String * filename) if (result != NULL) return result; - if (ext->isEqual(MCSTR("jpg"))) { - return MCSTR("image/jpeg"); - } - else if (ext->isEqual(MCSTR("jpeg"))) { - return MCSTR("image/jpeg"); - } - else if (ext->isEqual(MCSTR("png"))) { - return MCSTR("image/png"); - } - else if (ext->isEqual(MCSTR("gif"))) { - return MCSTR("image/gif"); - } - else if (ext->isEqual(MCSTR("html"))) { - return MCSTR("text/html"); - } - else if (ext->isEqual(MCSTR("txt"))) { - return MCSTR("text/plain"); - } - return NULL; + if (ext->isEqual(MCSTR("jpg"))) { + return MCSTR("image/jpeg"); + } + else if (ext->isEqual(MCSTR("jpeg"))) { + return MCSTR("image/jpeg"); + } + else if (ext->isEqual(MCSTR("png"))) { + return MCSTR("image/png"); + } + else if (ext->isEqual(MCSTR("gif"))) { + return MCSTR("image/gif"); + } + else if (ext->isEqual(MCSTR("html"))) { + return MCSTR("text/html"); + } + else if (ext->isEqual(MCSTR("txt"))) { + return MCSTR("text/plain"); + } + return NULL; } Attachment * Attachment::attachmentWithContentsOfFile(String * filename) @@ -154,58 +154,58 @@ Attachment * Attachment::attachmentWithContentsOfFile(String * filename) Attachment * Attachment::attachmentWithData(String * filename, Data * data) { Attachment * attachment; - String * mimeType; - + String * mimeType; + attachment = new Attachment(); mimeType = Attachment::mimeTypeForFilename(filename); - if (mimeType != NULL) { + if (mimeType != NULL) { attachment->setMimeType(mimeType); - } + } if (filename != NULL) { attachment->setFilename(filename->lastPathComponent()); } attachment->setData(data); - - return (Attachment *) attachment->autorelease(); + + return (Attachment *) attachment->autorelease(); } Attachment * Attachment::attachmentWithHTMLString(String * htmlString) { - Data * data; - Attachment * attachment; - + Data * data; + Attachment * attachment; + attachment = new Attachment(); - attachment->setInlineAttachment(true); + attachment->setInlineAttachment(true); attachment->setMimeType(MCSTR("text/html")); - data = htmlString->dataUsingEncoding("utf-8"); + data = htmlString->dataUsingEncoding("utf-8"); attachment->setData(data); - - return (Attachment *) attachment->autorelease(); + + return (Attachment *) attachment->autorelease(); } Attachment * Attachment::attachmentWithRFC822Message(Data * messageData) { - Attachment * attachment; - + Attachment * attachment; + attachment = new Attachment(); attachment->setMimeType(MCSTR("message/rfc822")); attachment->setData(messageData); - - return (Attachment *) attachment->autorelease(); + + return (Attachment *) attachment->autorelease(); } Attachment * Attachment::attachmentWithText(String * text) { - Data * data; - Attachment * attachment; - + Data * data; + Attachment * attachment; + attachment = new Attachment(); - attachment->setInlineAttachment(true); + attachment->setInlineAttachment(true); attachment->setMimeType(MCSTR("text/plain")); - data = text->dataUsingEncoding("utf-8"); + data = text->dataUsingEncoding("utf-8"); attachment->setData(data); - - return (Attachment *) attachment->autorelease(); + + return (Attachment *) attachment->autorelease(); } void Attachment::init() @@ -278,12 +278,12 @@ Data * Attachment::data() String * Attachment::decodedString() { - if (mData) { - return decodedStringForData(mData); - } - else { - return NULL; - } + if (mData) { + return decodedStringForData(mData); + } + else { + return NULL; + } } @@ -294,62 +294,62 @@ AbstractPart * Attachment::attachmentsWithMIME(struct mailmime * mime) void Attachment::fillMultipartSubAttachments(AbstractMultipart * multipart, struct mailmime * mime) { - switch (mime->mm_type) { - case MAILMIME_MULTIPLE: - { - clistiter * cur; + switch (mime->mm_type) { + case MAILMIME_MULTIPLE: + { + clistiter * cur; Array * subAttachments = Array::array(); - for(cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) { - struct mailmime * submime; + for(cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) { + struct mailmime * submime; AbstractPart * subAttachment; - - submime = (struct mailmime *) clist_content(cur); + + submime = (struct mailmime *) clist_content(cur); subAttachment = attachmentsWithMIMEWithMain(submime, false); - subAttachments->addObject(subAttachment); - } - + subAttachments->addObject(subAttachment); + } + multipart->setParts(subAttachments); break; - } + } } } AbstractPart * Attachment::attachmentsWithMIMEWithMain(struct mailmime * mime, bool isMain) { - switch (mime->mm_type) { - case MAILMIME_SINGLE: - { - Attachment * attachment; + switch (mime->mm_type) { + case MAILMIME_SINGLE: + { + Attachment * attachment; attachment = attachmentWithSingleMIME(mime); return attachment; - } - case MAILMIME_MULTIPLE: - { - if ((mime->mm_content_type != NULL) && (mime->mm_content_type->ct_subtype != NULL) && - (strcasecmp(mime->mm_content_type->ct_subtype, "alternative") == 0)) { - Multipart * attachment; + } + case MAILMIME_MULTIPLE: + { + if ((mime->mm_content_type != NULL) && (mime->mm_content_type->ct_subtype != NULL) && + (strcasecmp(mime->mm_content_type->ct_subtype, "alternative") == 0)) { + Multipart * attachment; attachment = new Multipart(); attachment->setPartType(PartTypeMultipartAlternative); fillMultipartSubAttachments(attachment, mime); return (Multipart *) attachment->autorelease(); - } - else if ((mime->mm_content_type != NULL) && (mime->mm_content_type->ct_subtype != NULL) && + } + else if ((mime->mm_content_type != NULL) && (mime->mm_content_type->ct_subtype != NULL) && (strcasecmp(mime->mm_content_type->ct_subtype, "related") == 0)) { - Multipart * attachment; + Multipart * attachment; attachment = new Multipart(); attachment->setPartType(PartTypeMultipartRelated); fillMultipartSubAttachments(attachment, mime); return (Multipart *) attachment->autorelease(); - } - else { - Multipart * attachment; + } + else { + Multipart * attachment; attachment = new Multipart(); fillMultipartSubAttachments(attachment, mime); return (Multipart *) attachment->autorelease(); - } - } - case MAILMIME_MESSAGE: - { + } + } + case MAILMIME_MESSAGE: + { if (isMain) { AbstractPart * attachment; attachment = attachmentsWithMIMEWithMain(mime->mm_data.mm_message.mm_msg_mime, false); @@ -360,10 +360,10 @@ AbstractPart * Attachment::attachmentsWithMIMEWithMain(struct mailmime * mime, b messagePart = attachmentWithMessageMIME(mime); return messagePart; } - } - } - - return NULL; + } + } + + return NULL; } Encoding Attachment::encodingForMIMEEncoding(struct mailmime_mechanism * mechanism, int defaultMimeEncoding) @@ -405,106 +405,107 @@ Encoding Attachment::encodingForMIMEEncoding(struct mailmime_mechanism * mechani static const char * get_discrete_type(struct mailmime_discrete_type * discrete_type) { - switch (discrete_type->dt_type) { - case MAILMIME_DISCRETE_TYPE_TEXT: - return "text"; - - case MAILMIME_DISCRETE_TYPE_IMAGE: - return "image"; - - case MAILMIME_DISCRETE_TYPE_AUDIO: - return "audio"; - - case MAILMIME_DISCRETE_TYPE_VIDEO: - return "video"; - - case MAILMIME_DISCRETE_TYPE_APPLICATION: - return "application"; - - case MAILMIME_DISCRETE_TYPE_EXTENSION: - return discrete_type->dt_extension; - } - - return NULL; + switch (discrete_type->dt_type) { + case MAILMIME_DISCRETE_TYPE_TEXT: + return "text"; + + case MAILMIME_DISCRETE_TYPE_IMAGE: + return "image"; + + case MAILMIME_DISCRETE_TYPE_AUDIO: + return "audio"; + + case MAILMIME_DISCRETE_TYPE_VIDEO: + return "video"; + + case MAILMIME_DISCRETE_TYPE_APPLICATION: + return "application"; + + case MAILMIME_DISCRETE_TYPE_EXTENSION: + return discrete_type->dt_extension; + } + + return NULL; } static const char * get_composite_type(struct mailmime_composite_type * composite_type) { - switch (composite_type->ct_type) { - case MAILMIME_COMPOSITE_TYPE_MESSAGE: - return "message"; - - case MAILMIME_COMPOSITE_TYPE_MULTIPART: - return "multipart"; - - case MAILMIME_COMPOSITE_TYPE_EXTENSION: - return composite_type->ct_token; - } - - return NULL; + switch (composite_type->ct_type) { + case MAILMIME_COMPOSITE_TYPE_MESSAGE: + return "message"; + + case MAILMIME_COMPOSITE_TYPE_MULTIPART: + return "multipart"; + + case MAILMIME_COMPOSITE_TYPE_EXTENSION: + return composite_type->ct_token; + } + + return NULL; } static char * get_content_type_str(struct mailmime_content * content) { - const char * str; - char * result; - const char * subtype; + const char * str; + char * result; + const char * subtype; if (content == NULL) { return strdup("unknown/unknown"); } - str = "unknown"; - - switch (content->ct_type->tp_type) { - case MAILMIME_TYPE_DISCRETE_TYPE: - str = get_discrete_type(content->ct_type->tp_data.tp_discrete_type); - break; - - case MAILMIME_TYPE_COMPOSITE_TYPE: - str = get_composite_type(content->ct_type->tp_data.tp_composite_type); - break; - } - - if (str == NULL) - str = "unknown"; - subtype = content->ct_subtype; + str = "unknown"; + + switch (content->ct_type->tp_type) { + case MAILMIME_TYPE_DISCRETE_TYPE: + str = get_discrete_type(content->ct_type->tp_data.tp_discrete_type); + break; + + case MAILMIME_TYPE_COMPOSITE_TYPE: + str = get_composite_type(content->ct_type->tp_data.tp_composite_type); + break; + } + + if (str == NULL) + str = "unknown"; + subtype = content->ct_subtype; if (subtype == NULL) subtype = "unknown"; - result = (char *) malloc(strlen(str) + strlen(subtype) + 2); - strcpy(result, str); - strcat(result, "/"); - strcat(result, subtype); - - return result; + result = (char *) malloc(strlen(str) + strlen(subtype) + 2); + strcpy(result, str); + strcat(result, "/"); + strcat(result, subtype); + + return result; } Attachment * Attachment::attachmentWithSingleMIME(struct mailmime * mime) { - struct mailmime_data * data; - const char * bytes; - size_t length; - Attachment * result; - struct mailmime_single_fields single_fields; - char * str; - char * name; - char * filename; + struct mailmime_data * data; + const char * bytes; + size_t length; + Attachment * result; + struct mailmime_single_fields single_fields; + char * str; + char * name; + char * filename; char * content_id; + char * description; char * loc; - Encoding encoding; + Encoding encoding; + + MCAssert(mime->mm_type == MAILMIME_SINGLE); - MCAssert(mime->mm_type == MAILMIME_SINGLE); - result = new Attachment(); - result->setUniqueID(mailcore::String::uuidString()); + result->setUniqueID(mailcore::String::uuidString()); - data = mime->mm_data.mm_single; - bytes = data->dt_data.dt_text.dt_data; - length = data->dt_data.dt_text.dt_length; + data = mime->mm_data.mm_single; + bytes = data->dt_data.dt_text.dt_data; + length = data->dt_data.dt_text.dt_length; - mailmime_single_fields_init(&single_fields, mime->mm_mime_fields, mime->mm_content_type); + mailmime_single_fields_init(&single_fields, mime->mm_mime_fields, mime->mm_content_type); encoding = encodingForMIMEEncoding(single_fields.fld_encoding, data->dt_encoding); @@ -512,52 +513,56 @@ Attachment * Attachment::attachmentWithSingleMIME(struct mailmime * mime) mimeData = Data::dataWithBytes(bytes, (unsigned int) length); mimeData = mimeData->decodedDataUsingEncoding(encoding); result->setData(mimeData); - - str = get_content_type_str(mime->mm_content_type); - result->setMimeType(String::stringWithUTF8Characters(str)); - free(str); - - name = single_fields.fld_content_name; - filename = single_fields.fld_disposition_filename; + + str = get_content_type_str(mime->mm_content_type); + result->setMimeType(String::stringWithUTF8Characters(str)); + free(str); + + name = single_fields.fld_content_name; + filename = single_fields.fld_disposition_filename; content_id = single_fields.fld_id; - loc = single_fields.fld_location; + description = single_fields.fld_description; + loc = single_fields.fld_location; - if (filename != NULL) { - result->setFilename(String::stringByDecodingMIMEHeaderValue(filename)); - } - else if (name != NULL) { + if (filename != NULL) { + result->setFilename(String::stringByDecodingMIMEHeaderValue(filename)); + } + else if (name != NULL) { result->setFilename(String::stringByDecodingMIMEHeaderValue(name)); - } - if (content_id != NULL) { + } + if (content_id != NULL) { result->setContentID(String::stringWithUTF8Characters(content_id)); } - if (single_fields.fld_content_charset != NULL) { + if (description != NULL) { + result->setContentDescription(String::stringWithUTF8Characters(description)); + } + if (single_fields.fld_content_charset != NULL) { result->setCharset(String::stringByDecodingMIMEHeaderValue(single_fields.fld_content_charset)); - } + } if (loc != NULL) { result->setContentLocation(String::stringWithUTF8Characters(loc)); } - if (single_fields.fld_disposition != NULL) { - if (single_fields.fld_disposition->dsp_type != NULL) { - if (single_fields.fld_disposition->dsp_type->dsp_type == MAILMIME_DISPOSITION_TYPE_INLINE) { + if (single_fields.fld_disposition != NULL) { + if (single_fields.fld_disposition->dsp_type != NULL) { + if (single_fields.fld_disposition->dsp_type->dsp_type == MAILMIME_DISPOSITION_TYPE_INLINE) { result->setInlineAttachment(true); - } - } - } - - return (Attachment *) result->autorelease(); + } + } + } + + return (Attachment *) result->autorelease(); } MessagePart * Attachment::attachmentWithMessageMIME(struct mailmime * mime) { - MessagePart * attachment; + MessagePart * attachment; AbstractPart * mainPart; - + attachment = new MessagePart(); attachment->header()->importIMFFields(mime->mm_data.mm_message.mm_fields); mainPart = attachmentsWithMIMEWithMain(mime->mm_data.mm_message.mm_msg_mime, false); - attachment->setMainPart(mainPart); - - return (MessagePart *) attachment->autorelease(); + attachment->setMainPart(mainPart); + + return (MessagePart *) attachment->autorelease(); } diff --git a/src/core/rfc822/MCMessageBuilder.cc b/src/core/rfc822/MCMessageBuilder.cc index dd0bee81..262e1180 100644 --- a/src/core/rfc822/MCMessageBuilder.cc +++ b/src/core/rfc822/MCMessageBuilder.cc @@ -133,6 +133,7 @@ err: } static struct mailmime * get_text_part(const char * mime_type, const char * charset, const char * content_id, + const char * description, const char * text, size_t length, int encoding_type) { struct mailmime_fields * mime_fields; @@ -142,6 +143,7 @@ static struct mailmime * get_text_part(const char * mime_type, const char * char struct mailmime_disposition * disposition; struct mailmime_mechanism * encoding; char * dup_content_id; + char * dup_description; encoding = mailmime_mechanism_new(encoding_type, NULL); disposition = mailmime_disposition_new_with_data(MAILMIME_DISPOSITION_TYPE_INLINE, @@ -149,8 +151,11 @@ static struct mailmime * get_text_part(const char * mime_type, const char * char dup_content_id = NULL; if (content_id != NULL) dup_content_id = strdup(content_id); + dup_description = NULL; + if (dup_description != NULL) + dup_description = strdup(description); mime_fields = mailmime_fields_new_with_data(encoding, - dup_content_id, NULL, disposition, NULL); + dup_content_id, dup_description, disposition, NULL); content = mailmime_content_new_with_str(mime_type); if (charset == NULL) { @@ -167,6 +172,7 @@ static struct mailmime * get_text_part(const char * mime_type, const char * char } static struct mailmime * get_plain_text_part(const char * mime_type, const char * charset, const char * content_id, + const char * description, const char * text, size_t length) { bool needsQuotedPrintable; @@ -183,13 +189,14 @@ static struct mailmime * get_plain_text_part(const char * mime_type, const char if (needsQuotedPrintable) { mechanism = MAILMIME_MECHANISM_QUOTED_PRINTABLE; } - return get_text_part(mime_type, charset, content_id, text, length, mechanism); + return get_text_part(mime_type, charset, content_id, description, text, length, mechanism); } static struct mailmime * get_other_text_part(const char * mime_type, const char * charset, const char * content_id, + const char * description, const char * text, size_t length) { - return get_text_part(mime_type, charset, content_id, text, length, MAILMIME_MECHANISM_QUOTED_PRINTABLE); + return get_text_part(mime_type, charset, content_id, description, text, length, MAILMIME_MECHANISM_QUOTED_PRINTABLE); } static struct mailmime * get_file_part(const char * filename, const char * mime_type, int is_inline, @@ -237,6 +244,8 @@ static struct mailmime * get_file_part(const char * filename, const char * mime_ return mime; } +#define MIME_ENCODED_STR(str) (str != NULL ? str->encodedMIMEHeaderValue()->bytes() : NULL) + static struct mailmime * mime_from_attachment(Attachment * att) { struct mailmime * mime; @@ -256,18 +265,20 @@ static struct mailmime * mime_from_attachment(Attachment * att) else if (att->isInlineAttachment() && att->mimeType()->lowercaseString()->isEqual(MCSTR("text/plain"))) { mime = get_plain_text_part(MCUTF8(att->mimeType()), MCUTF8(att->charset()), MCUTF8(att->contentID()), + MIME_ENCODED_STR(att->contentDescription()), data->bytes(), data->length()); } else if (att->isInlineAttachment() && att->mimeType()->lowercaseString()->hasPrefix(MCSTR("text/"))) { mime = get_other_text_part(MCUTF8(att->mimeType()), MCUTF8(att->charset()), MCUTF8(att->contentID()), + MIME_ENCODED_STR(att->contentDescription()), data->bytes(), data->length()); } else { - mime = get_file_part(att->filename()->encodedMIMEHeaderValue()->bytes(), + mime = get_file_part(MIME_ENCODED_STR(att->filename()), MCUTF8(att->mimeType()), att->isInlineAttachment(), MCUTF8(att->contentID()), - att->contentDescription()->encodedMIMEHeaderValue()->bytes(), + MIME_ENCODED_STR(att->contentDescription()), data->bytes(), data->length()); } return mime; |