Mercurial > dovecot > core-2.2
changeset 21947:f98d4d45e16e
lib-imap: imap-bodystructure: Fixed handling of a multipart part without children in imap_bodystructure_parse().
In imap_bodystructure_write(), an empty multipart part is addressed by generating an empty text/plain part.
However, when parsing that back with imap_bodystructure_parse() against a parsed message_part tree, this case needs to be considered explicitly.
Otherwise, it will not be able to match the message part hierarchies.
This adds a test suite item that tests both the write (previous commit) and parse functions.
author | Stephan Bosch <stephan.bosch@dovecot.fi> |
---|---|
date | Tue, 11 Apr 2017 09:34:11 +0200 |
parents | dd009c471bd2 |
children | 52684cb827cd |
files | src/lib-imap/imap-bodystructure.c src/lib-imap/test-imap-bodystructure.c |
diffstat | 2 files changed, 50 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-imap/imap-bodystructure.c Wed Apr 12 10:13:15 2017 +0200 +++ b/src/lib-imap/imap-bodystructure.c Tue Apr 11 09:34:11 2017 +0200 @@ -377,10 +377,25 @@ multipart = FALSE; if (!parsing_tree) { - child_part = part->children; - while (args->type == IMAP_ARG_LIST) { - if ((part->flags & MESSAGE_PART_FLAG_MULTIPART) == 0 || - child_part == NULL) { + if ((part->flags & MESSAGE_PART_FLAG_MULTIPART) != 0 && + part->children == NULL) { + struct message_part_data dummy_part_data = { + .content_type = "text", + .content_subtype = "plain", + .content_transfer_encoding = "7bit" + }; + struct message_part dummy_part = { + .parent = part, + .data = &dummy_part_data, + .flags = MESSAGE_PART_FLAG_TEXT + }; + struct message_part *dummy_partp = &dummy_part; + + /* no parts in multipart message, + that's not allowed. expect a single + 0-length text/plain structure */ + if (args->type != IMAP_ARG_LIST || + (args+1)->type == IMAP_ARG_LIST) { *error_r = "message_part hierarchy " "doesn't match BODYSTRUCTURE"; return -1; @@ -388,14 +403,33 @@ list_args = imap_arg_as_list(args); if (imap_bodystructure_parse_args(list_args, pool, - &child_part, error_r) < 0) + &dummy_partp, error_r) < 0) return -1; - child_part = child_part->next; + child_part = NULL; multipart = TRUE; args++; + + } else { + child_part = part->children; + while (args->type == IMAP_ARG_LIST) { + if ((part->flags & MESSAGE_PART_FLAG_MULTIPART) == 0 || + child_part == NULL) { + *error_r = "message_part hierarchy " + "doesn't match BODYSTRUCTURE"; + return -1; + } + + list_args = imap_arg_as_list(args); + if (imap_bodystructure_parse_args(list_args, pool, + &child_part, error_r) < 0) + return -1; + child_part = child_part->next; + + multipart = TRUE; + args++; + } } - if (multipart) { if (child_part != NULL) { *error_r = "message_part hierarchy "
--- a/src/lib-imap/test-imap-bodystructure.c Wed Apr 12 10:13:15 2017 +0200 +++ b/src/lib-imap/test-imap-bodystructure.c Tue Apr 11 09:34:11 2017 +0200 @@ -224,6 +224,15 @@ "(\"text\" \"x-myown\" (\"charset\" \"us-ascii\" \"foo\" \"quoted\\\"string\") \"<foo@example.com>\" \"hellodescription\" \"7bit\" 7 1 \"Q2hlY2sgSW50ZWdyaXR5IQ==\" (\"inline\" (\"foo\" \"bar\")) (\"en\" \"fi\" \"se\") \"http://example.com/test.txt\")(\"message\" \"rfc822\" NIL NIL NIL \"7bit\" 412 (\"Sun, 12 Aug 2012 12:34:56 +0300\" \"submsg\" ((NIL NIL \"sub\" \"domain.org\")) ((NIL NIL \"sub\" \"domain.org\")) ((NIL NIL \"sub\" \"domain.org\")) ((NIL NIL \"sub-to1\" \"domain.org\")(NIL NIL \"sub-to2\" \"domain.org\")) NIL NIL NIL NIL) ((\"text\" \"html\" (\"charset\" \"us-ascii\") NIL NIL \"8bit\" 20 1 NIL NIL NIL NIL)(\"text\" \"plain\" (\"charset\" \"us-ascii\") NIL NIL \"7bit\" 21 1 NIL NIL NIL NIL) \"alternative\" (\"boundary\" \"sub1\") NIL NIL NIL) 21 NIL NIL NIL NIL) \"mixed\" (\"boundary\" \"foo bar\") NIL NIL NIL", .body = "(\"text\" \"x-myown\" (\"charset\" \"us-ascii\" \"foo\" \"quoted\\\"string\") \"<foo@example.com>\" \"hellodescription\" \"7bit\" 7 1)(\"message\" \"rfc822\" NIL NIL NIL \"7bit\" 412 (\"Sun, 12 Aug 2012 12:34:56 +0300\" \"submsg\" ((NIL NIL \"sub\" \"domain.org\")) ((NIL NIL \"sub\" \"domain.org\")) ((NIL NIL \"sub\" \"domain.org\")) ((NIL NIL \"sub-to1\" \"domain.org\")(NIL NIL \"sub-to2\" \"domain.org\")) NIL NIL NIL NIL) ((\"text\" \"html\" (\"charset\" \"us-ascii\") NIL NIL \"8bit\" 20 1)(\"text\" \"plain\" (\"charset\" \"us-ascii\") NIL NIL \"7bit\" 21 1) \"alternative\") 21) \"mixed\"" + },{ + .message = + "Content-Type: multipart/mixed; boundary=\"foo\"\n" + "\n", + .bodystructure = + "(\"text\" \"plain\" (\"charset\" \"us-ascii\") NIL NIL \"7bit\" 0 0 NIL NIL NIL NIL) \"mixed\" (\"boundary\" \"foo\") NIL NIL NIL", + .body = + "(\"text\" \"plain\" (\"charset\" \"us-ascii\") NIL NIL \"7bit\" 0 0) \"mixed\"" + } };