aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/rfc822
diff options
context:
space:
mode:
authorGravatar Hoa V. Dinh <dinh.viet.hoa@gmail.com>2013-09-03 20:33:21 -0700
committerGravatar Hoa V. Dinh <dinh.viet.hoa@gmail.com>2013-09-03 20:33:21 -0700
commit79253cf925c48e3740f28d75ece8c0a319872678 (patch)
tree2591ffd48b861f47fcf8e36746145c19eb1e45d0 /src/core/rfc822
parent325e9353182e49cb87e91ae44ad0fb7452f360d9 (diff)
Improved Content-Description support and fixed crash (Fixed #350)
Diffstat (limited to 'src/core/rfc822')
-rw-r--r--src/core/rfc822/MCAttachment.cc379
-rw-r--r--src/core/rfc822/MCMessageBuilder.cc21
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;