test-message-parser.c revision baf3e87e186453fda13bd21f7cbcb2efc8492e8b
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (c) 2007-2016 Dovecot authors, see the included COPYING file */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "lib.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "str.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "istream.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "message-parser.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "test-common.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic const char test_msg[] =
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"Return-Path: <test@example.org>\n"
6d573191bea1a64d6046be070487a5705a2d0204Stephan Bosch"Subject: Hello world\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"From: Test User <test@example.org>\n"
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen"To: Another User <test2@example.org>\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"Message-Id: <1.2.3.4@example>\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"Mime-Version: 1.0\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"Date: Sun, 23 May 2007 04:58:08 +0300\n"
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen"Content-Type: multipart/signed; micalg=pgp-sha1;\n"
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen" protocol=\"application/pgp-signature\";\n"
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen" boundary=\"=-GNQXLhuj24Pl1aCkk4/d\"\n"
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen"\n"
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen"--=-GNQXLhuj24Pl1aCkk4/d\n"
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen"Content-Type: text/plain\n"
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen"Content-Transfer-Encoding: quoted-printable\n"
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen"\n"
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen"There was a day=20\n"
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen"a happy=20day\n"
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen"\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"--=-GNQXLhuj24Pl1aCkk4/d\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"Content-Type: application/pgp-signature; name=signature.asc\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"-----BEGIN PGP SIGNATURE-----\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"Version: GnuPG v1.2.4 (GNU/Linux)\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"invalid\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"-----END PGP SIGNATURE-----\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"--=-GNQXLhuj24Pl1aCkk4/d--\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"\n";
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#define TEST_MSG_LEN (sizeof(test_msg)-1)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic bool msg_parts_cmp(struct message_part *p1, struct message_part *p2)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch while (p1 != NULL || p2 != NULL) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if ((p1 != NULL) != (p2 != NULL))
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return FALSE;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if ((p1->children != NULL) != (p2->children != NULL))
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return FALSE;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (p1->children != NULL) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (!msg_parts_cmp(p1->children, p2->children))
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return FALSE;
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (p1->physical_pos != p2->physical_pos ||
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch p1->header_size.physical_size != p2->header_size.physical_size ||
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch p1->header_size.virtual_size != p2->header_size.virtual_size ||
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch p1->header_size.lines != p2->header_size.lines ||
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch p1->body_size.physical_size != p2->body_size.physical_size ||
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch p1->body_size.virtual_size != p2->body_size.virtual_size ||
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch p1->body_size.lines != p2->body_size.lines ||
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch p1->flags != p2->flags)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return FALSE;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch p1 = p1->next;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch p2 = p2->next;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return TRUE;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic void test_parsed_parts(struct istream *input, struct message_part *parts)
069def4dc35022852d569b7ab75a3b19d2cb0f1cTimo Sirainen{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct message_parser_ctx *parser;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct message_block block;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct message_part *parts2;
6d573191bea1a64d6046be070487a5705a2d0204Stephan Bosch uoff_t i, input_size;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const char *error;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch int ret;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch i_stream_seek(input, 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (i_stream_get_size(input, TRUE, &input_size) < 0)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch i_unreached();
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch parser = message_parser_init_from_parts(parts, input, 0,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch for (i = 1; i <= input_size*2+1; i++) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_istream_set_size(input, i/2);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (i > TEST_MSG_LEN*2)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_istream_set_allow_eof(input, TRUE);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch while ((ret = message_parser_parse_next_block(parser,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch &block)) > 0) ;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(message_parser_deinit_from_parts(&parser, &parts2, &error) == 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(msg_parts_cmp(parts, parts2));
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
fe681e6db72f30bd754b622005bbe298e5ca775aTimo Sirainenstatic void test_message_parser_small_blocks(void)
fe681e6db72f30bd754b622005bbe298e5ca775aTimo Sirainen{
fe681e6db72f30bd754b622005bbe298e5ca775aTimo Sirainen struct message_parser_ctx *parser;
fe681e6db72f30bd754b622005bbe298e5ca775aTimo Sirainen struct istream *input;
fe681e6db72f30bd754b622005bbe298e5ca775aTimo Sirainen struct message_part *parts, *parts2;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct message_block block;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch unsigned int i, end_of_headers_idx;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch string_t *output;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch pool_t pool;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const char *error;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch int ret;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
fb1be3de0159d6a10e916ad992e2bc53be64c6d5Timo Sirainen test_begin("message parser in small blocks");
fb1be3de0159d6a10e916ad992e2bc53be64c6d5Timo Sirainen pool = pool_alloconly_create("message parser", 10240);
fb1be3de0159d6a10e916ad992e2bc53be64c6d5Timo Sirainen input = test_istream_create(test_msg);
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen output = t_str_new(128);
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen /* full parsing */
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen parser = message_parser_init(pool, input, 0,
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen MESSAGE_PARSER_FLAG_INCLUDE_MULTIPART_BLOCKS |
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen MESSAGE_PARSER_FLAG_INCLUDE_BOUNDARIES);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch while ((ret = message_parser_parse_next_block(parser, &block)) > 0) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (block.hdr != NULL)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch message_header_line_write(output, block.hdr);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch else if (block.size > 0)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch str_append_n(output, block.data, block.size);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(ret < 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch message_parser_deinit(&parser, &parts);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(strcmp(test_msg, str_c(output)) == 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* parsing in small blocks */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch i_stream_seek(input, 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_istream_set_allow_eof(input, FALSE);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch parser = message_parser_init(pool, input, 0, 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch for (i = 1; i <= TEST_MSG_LEN*2+1; i++) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_istream_set_size(input, i/2);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (i > TEST_MSG_LEN*2)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_istream_set_allow_eof(input, TRUE);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch while ((ret = message_parser_parse_next_block(parser,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch &block)) > 0) ;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert((ret == 0 && i <= TEST_MSG_LEN*2) ||
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch (ret < 0 && i > TEST_MSG_LEN*2));
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch message_parser_deinit(&parser, &parts2);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(msg_parts_cmp(parts, parts2));
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* parsing in small blocks from preparsed parts */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch i_stream_seek(input, 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_istream_set_allow_eof(input, FALSE);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch end_of_headers_idx = (strstr(test_msg, "\n-----") - test_msg);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch parser = message_parser_init_from_parts(parts, input, 0,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch for (i = 1; i <= TEST_MSG_LEN*2+1; i++) {
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_istream_set_size(input, i/2);
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch if (i > TEST_MSG_LEN*2)
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_istream_set_allow_eof(input, TRUE);
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch while ((ret = message_parser_parse_next_block(parser,
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch &block)) > 0) ;
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_assert((ret == 0 && i/2 <= end_of_headers_idx) ||
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch (ret < 0 && i/2 > end_of_headers_idx));
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch }
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_assert(message_parser_deinit_from_parts(&parser, &parts2, &error) == 0);
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_assert(msg_parts_cmp(parts, parts2));
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch i_stream_unref(&input);
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch pool_unref(&pool);
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_end();
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch}
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Boschstatic void test_message_parser_truncated_mime_headers(void)
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch{
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Boschstatic const char input_msg[] =
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch"Content-Type: multipart/mixed; boundary=\":foo\"\n"
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch"\n"
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch"--:foo\n"
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch"--:foo\n"
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch"Content-Type: text/plain\n"
b99130e4cf4af4e6b103b949456222f3a2dff424Timo Sirainen"--:foo\n"
b99130e4cf4af4e6b103b949456222f3a2dff424Timo Sirainen"Content-Type: text/plain\r\n"
b99130e4cf4af4e6b103b949456222f3a2dff424Timo Sirainen"--:foo\n"
b99130e4cf4af4e6b103b949456222f3a2dff424Timo Sirainen"Content-Type: text/html\n"
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch"--:foo--\n";
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct message_parser_ctx *parser;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct istream *input;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct message_part *parts, *part;
6d573191bea1a64d6046be070487a5705a2d0204Stephan Bosch struct message_block block;
6d573191bea1a64d6046be070487a5705a2d0204Stephan Bosch pool_t pool;
6d573191bea1a64d6046be070487a5705a2d0204Stephan Bosch int ret;
6d573191bea1a64d6046be070487a5705a2d0204Stephan Bosch
6d573191bea1a64d6046be070487a5705a2d0204Stephan Bosch test_begin("message parser truncated mime headers");
6d573191bea1a64d6046be070487a5705a2d0204Stephan Bosch pool = pool_alloconly_create("message parser", 10240);
6d573191bea1a64d6046be070487a5705a2d0204Stephan Bosch input = test_istream_create(input_msg);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch parser = message_parser_init(pool, input, 0, 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
4521d35c263add6af3f1ae55b3760291767ce50cTimo Sirainen test_assert(ret < 0);
4521d35c263add6af3f1ae55b3760291767ce50cTimo Sirainen message_parser_deinit(&parser, &parts);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen test_assert((parts->flags & MESSAGE_PART_FLAG_MULTIPART) != 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->header_size.lines == 2);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->header_size.physical_size == 48);
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen test_assert(parts->header_size.virtual_size == 48+2);
4521d35c263add6af3f1ae55b3760291767ce50cTimo Sirainen test_assert(parts->body_size.lines == 8);
4521d35c263add6af3f1ae55b3760291767ce50cTimo Sirainen test_assert(parts->body_size.physical_size == 112);
4521d35c263add6af3f1ae55b3760291767ce50cTimo Sirainen test_assert(parts->body_size.virtual_size == 112+7);
4521d35c263add6af3f1ae55b3760291767ce50cTimo Sirainen test_assert(parts->children->physical_pos == 55);
4521d35c263add6af3f1ae55b3760291767ce50cTimo Sirainen test_assert(parts->children->header_size.physical_size == 0);
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen test_assert(parts->children->body_size.physical_size == 0);
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen test_assert(parts->children->body_size.lines == 0);
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen test_assert(parts->children->next->physical_pos == 62);
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen test_assert(parts->children->next->header_size.physical_size == 24);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->next->header_size.virtual_size == 24);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->next->header_size.lines == 0);
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen test_assert(parts->children->next->next->physical_pos == 94);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->next->next->header_size.physical_size == 24);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->next->next->header_size.virtual_size == 24);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->next->next->header_size.lines == 0);
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen test_assert(parts->children->next->next->next->physical_pos == 127);
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen test_assert(parts->children->next->next->next->header_size.physical_size == 23);
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen test_assert(parts->children->next->next->next->header_size.virtual_size == 23);
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen test_assert(parts->children->next->next->next->header_size.lines == 0);
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen for (part = parts->children; part != NULL; part = part->next) {
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen test_assert(part->body_size.physical_size == 0);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(part->body_size.virtual_size == 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->next->next->next->next == NULL);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_parsed_parts(input, parts);
6d573191bea1a64d6046be070487a5705a2d0204Stephan Bosch i_stream_unref(&input);
6d573191bea1a64d6046be070487a5705a2d0204Stephan Bosch pool_unref(&pool);
6d573191bea1a64d6046be070487a5705a2d0204Stephan Bosch test_end();
6d573191bea1a64d6046be070487a5705a2d0204Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic void test_message_parser_truncated_mime_headers2(void)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Boschstatic const char input_msg[] =
57962a937b214be3a131f78005509afaa26fe4bfTimo Sirainen"Content-Type: multipart/mixed; boundary=\"ab\"\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"--ab\n"
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch"Content-Type: multipart/mixed; boundary=\"a\"\n"
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch"\n"
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch"--ab\n"
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch"Content-Type: text/plain\n"
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch"\n"
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch"--a\n\n";
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen struct message_parser_ctx *parser;
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch struct istream *input;
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch struct message_part *parts;
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch struct message_block block;
069b28a2ef54072a221fe4ac67aaeb4e83fee6c1Timo Sirainen pool_t pool;
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch int ret;
791fb70b3255a11a91ce0c2dc3ae1460d4cf8459Timo Sirainen
791fb70b3255a11a91ce0c2dc3ae1460d4cf8459Timo Sirainen test_begin("message parser truncated mime headers 2");
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch pool = pool_alloconly_create("message parser", 10240);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch input = test_istream_create(input_msg);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch parser = message_parser_init(pool, input, 0, 0);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(ret < 0);
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch message_parser_deinit(&parser, &parts);
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->header_size.lines == 2);
069b28a2ef54072a221fe4ac67aaeb4e83fee6c1Timo Sirainen test_assert(parts->header_size.physical_size == 46);
069b28a2ef54072a221fe4ac67aaeb4e83fee6c1Timo Sirainen test_assert(parts->header_size.virtual_size == 46+2);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->body_size.lines == 8);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->body_size.physical_size == 86);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->body_size.virtual_size == 86+8);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->physical_pos == 51);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->header_size.lines == 1);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->header_size.physical_size == 44);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->header_size.virtual_size == 44+1);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->body_size.lines == 0);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->body_size.physical_size == 0);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->children == NULL);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->next->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME));
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->next->physical_pos == 101);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->next->header_size.lines == 2);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->next->header_size.physical_size == 26);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->next->header_size.virtual_size == 26+2);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->next->body_size.lines == 2);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->next->body_size.physical_size == 5);
069b28a2ef54072a221fe4ac67aaeb4e83fee6c1Timo Sirainen test_assert(parts->children->next->body_size.virtual_size == 5+2);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->next->children == NULL);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen test_parsed_parts(input, parts);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch i_stream_unref(&input);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch pool_unref(&pool);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_end();
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch}
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Boschstatic void test_message_parser_truncated_mime_headers3(void)
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch{
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Boschstatic const char input_msg[] =
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch"Content-Type: multipart/mixed; boundary=\"ab\"\n";
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch struct message_parser_ctx *parser;
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch struct istream *input;
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch struct message_part *parts;
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch struct message_block block;
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch pool_t pool;
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch int ret;
fb025942616dfec7770455a7092d01f2e516314dTimo Sirainen
fb025942616dfec7770455a7092d01f2e516314dTimo Sirainen test_begin("message parser truncated mime headers 3");
fb025942616dfec7770455a7092d01f2e516314dTimo Sirainen pool = pool_alloconly_create("message parser", 10240);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch input = test_istream_create(input_msg);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch parser = message_parser_init(pool, input, 0, 0);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(ret < 0);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch message_parser_deinit(&parser, &parts);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->header_size.lines == 1);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->header_size.physical_size == 45);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->header_size.virtual_size == 45+1);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->body_size.lines == 0);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->body_size.physical_size == 0);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children == NULL);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_parsed_parts(input, parts);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch i_stream_unref(&input);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch pool_unref(&pool);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_end();
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch}
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Boschstatic void test_message_parser_empty_multipart(void)
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch{
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Boschstatic const char input_msg[] =
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch"Content-Type: multipart/mixed; boundary=\"ab\"\n"
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch"\n"
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch"body\n";
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch struct message_parser_ctx *parser;
069b28a2ef54072a221fe4ac67aaeb4e83fee6c1Timo Sirainen struct istream *input;
069b28a2ef54072a221fe4ac67aaeb4e83fee6c1Timo Sirainen struct message_part *parts;
069b28a2ef54072a221fe4ac67aaeb4e83fee6c1Timo Sirainen struct message_block block;
069b28a2ef54072a221fe4ac67aaeb4e83fee6c1Timo Sirainen pool_t pool;
069b28a2ef54072a221fe4ac67aaeb4e83fee6c1Timo Sirainen int ret;
069b28a2ef54072a221fe4ac67aaeb4e83fee6c1Timo Sirainen
069b28a2ef54072a221fe4ac67aaeb4e83fee6c1Timo Sirainen test_begin("message parser empty multipart");
069b28a2ef54072a221fe4ac67aaeb4e83fee6c1Timo Sirainen pool = pool_alloconly_create("message parser", 10240);
069b28a2ef54072a221fe4ac67aaeb4e83fee6c1Timo Sirainen input = test_istream_create(input_msg);
069b28a2ef54072a221fe4ac67aaeb4e83fee6c1Timo Sirainen
069b28a2ef54072a221fe4ac67aaeb4e83fee6c1Timo Sirainen parser = message_parser_init(pool, input, 0, 0);
069b28a2ef54072a221fe4ac67aaeb4e83fee6c1Timo Sirainen while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
069b28a2ef54072a221fe4ac67aaeb4e83fee6c1Timo Sirainen test_assert(ret < 0);
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch message_parser_deinit(&parser, &parts);
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch test_assert(parts->header_size.lines == 2);
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch test_assert(parts->header_size.physical_size == 46);
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch test_assert(parts->header_size.virtual_size == 46+2);
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch test_assert(parts->body_size.lines == 1);
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch test_assert(parts->body_size.physical_size == 5);
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch test_assert(parts->body_size.virtual_size == 5+1);
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen test_assert(parts->children == NULL);
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_parsed_parts(input, parts);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch i_stream_unref(&input);
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen pool_unref(&pool);
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen test_end();
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainenstatic void test_message_parser_duplicate_mime_boundary(void)
667de5cf294d833b3d47dd455bacff4fd68dd146Timo Sirainen{
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic const char input_msg[] =
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch"Content-Type: multipart/mixed; boundary=\"a\"\n"
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch"\n"
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch"--a\n"
fb025942616dfec7770455a7092d01f2e516314dTimo Sirainen"Content-Type: multipart/mixed; boundary=\"a\"\n"
fb025942616dfec7770455a7092d01f2e516314dTimo Sirainen"\n"
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen"--a\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"Content-Type: text/plain\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"\n"
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen"body\n";
50d1446e71cfbdc5b6d7bafcf91b7bff453989d3Stephan Bosch struct message_parser_ctx *parser;
50d1446e71cfbdc5b6d7bafcf91b7bff453989d3Stephan Bosch struct istream *input;
50d1446e71cfbdc5b6d7bafcf91b7bff453989d3Stephan Bosch struct message_part *parts;
50d1446e71cfbdc5b6d7bafcf91b7bff453989d3Stephan Bosch struct message_block block;
50d1446e71cfbdc5b6d7bafcf91b7bff453989d3Stephan Bosch pool_t pool;
50d1446e71cfbdc5b6d7bafcf91b7bff453989d3Stephan Bosch int ret;
50d1446e71cfbdc5b6d7bafcf91b7bff453989d3Stephan Bosch
50d1446e71cfbdc5b6d7bafcf91b7bff453989d3Stephan Bosch test_begin("message parser duplicate mime boundary");
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen pool = pool_alloconly_create("message parser", 10240);
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen input = test_istream_create(input_msg);
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch parser = message_parser_init(pool, input, 0, 0);
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
50d1446e71cfbdc5b6d7bafcf91b7bff453989d3Stephan Bosch test_assert(ret < 0);
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen message_parser_deinit(&parser, &parts);
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch test_assert(parts->header_size.lines == 2);
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen test_assert(parts->header_size.physical_size == 45);
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen test_assert(parts->header_size.virtual_size == 45+2);
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen test_assert(parts->body_size.lines == 7);
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen test_assert(parts->body_size.physical_size == 84);
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch test_assert(parts->body_size.virtual_size == 84+7);
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen test_assert(parts->children->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen test_assert(parts->children->physical_pos == 49);
50d1446e71cfbdc5b6d7bafcf91b7bff453989d3Stephan Bosch test_assert(parts->children->header_size.lines == 2);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->header_size.physical_size == 45);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->header_size.virtual_size == 45+2);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->body_size.lines == 4);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->body_size.physical_size == 35);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->body_size.virtual_size == 35+4);
fb025942616dfec7770455a7092d01f2e516314dTimo Sirainen test_assert(parts->children->children->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME));
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->children->physical_pos == 98);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->children->header_size.lines == 2);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->children->header_size.physical_size == 26);
069b28a2ef54072a221fe4ac67aaeb4e83fee6c1Timo Sirainen test_assert(parts->children->children->header_size.virtual_size == 26+2);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_assert(parts->children->children->body_size.lines == 1);
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch test_assert(parts->children->children->body_size.physical_size == 5);
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch test_assert(parts->children->children->body_size.virtual_size == 5+1);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_parsed_parts(input, parts);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch i_stream_unref(&input);
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch pool_unref(&pool);
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch test_end();
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch}
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Boschstatic void test_message_parser_garbage_suffix_mime_boundary(void)
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Bosch{
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Boschstatic const char input_msg[] =
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"Content-Type: multipart/mixed; boundary=\"a\"\n"
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen"\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"--ab\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"Content-Type: multipart/mixed; boundary=\"a\"\n"
ccd968b44a40b9c2cf6278fabfa2a80cc5d9e46bTimo Sirainen"\n"
ccd968b44a40b9c2cf6278fabfa2a80cc5d9e46bTimo Sirainen"--ac\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"Content-Type: text/plain\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"body\n";
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct message_parser_ctx *parser;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct istream *input;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct message_part *parts;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct message_block block;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch pool_t pool;
27421074812b84d144b68388e597f4700f4f1c1bStephan Bosch int ret;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_begin("message parser garbage suffix mime boundary");
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch pool = pool_alloconly_create("message parser", 10240);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch input = test_istream_create(input_msg);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch parser = message_parser_init(pool, input, 0, 0);
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_assert(ret < 0);
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch message_parser_deinit(&parser, &parts);
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_assert(parts->header_size.lines == 2);
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_assert(parts->header_size.physical_size == 45);
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_assert(parts->header_size.virtual_size == 45+2);
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_assert(parts->body_size.lines == 7);
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_assert(parts->body_size.physical_size == 86);
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_assert(parts->body_size.virtual_size == 86+7);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_assert(parts->children->physical_pos == 50);
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_assert(parts->children->header_size.lines == 2);
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_assert(parts->children->header_size.physical_size == 45);
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_assert(parts->children->header_size.virtual_size == 45+2);
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_assert(parts->children->body_size.lines == 4);
b99130e4cf4af4e6b103b949456222f3a2dff424Timo Sirainen test_assert(parts->children->body_size.physical_size == 36);
b99130e4cf4af4e6b103b949456222f3a2dff424Timo Sirainen test_assert(parts->children->body_size.virtual_size == 36+4);
b99130e4cf4af4e6b103b949456222f3a2dff424Timo Sirainen test_assert(parts->children->children->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME));
b99130e4cf4af4e6b103b949456222f3a2dff424Timo Sirainen test_assert(parts->children->children->physical_pos == 100);
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_assert(parts->children->children->header_size.lines == 2);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->children->header_size.physical_size == 26);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->children->header_size.virtual_size == 26+2);
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen test_assert(parts->children->children->body_size.lines == 1);
2ccb0bce340110ab68d1a490103d7b0271962139Stephan Bosch test_assert(parts->children->children->body_size.physical_size == 5);
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch test_assert(parts->children->children->body_size.virtual_size == 5+1);
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen test_parsed_parts(input, parts);
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen i_stream_unref(&input);
dd61a7356c4e00d733fd6cd99b29d979b9eb26dfTimo Sirainen pool_unref(&pool);
dd61a7356c4e00d733fd6cd99b29d979b9eb26dfTimo Sirainen test_end();
dd61a7356c4e00d733fd6cd99b29d979b9eb26dfTimo Sirainen}
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Boschstatic void test_message_parser_continuing_mime_boundary(void)
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch{
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Boschstatic const char input_msg[] =
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen"Content-Type: multipart/mixed; boundary=\"a\"\n"
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen"\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"--a\n"
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch"Content-Type: multipart/mixed; boundary=\"ab\"\n"
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch"\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"--ab\n"
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch"Content-Type: text/plain\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"\n"
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch"body\n";
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch struct message_parser_ctx *parser;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct istream *input;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct message_part *parts;
87c121a4c05b9cee46f1f757ec6999d441519abfStephan Bosch struct message_block block;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch pool_t pool;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch int ret;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_begin("message parser continuing mime boundary");
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch pool = pool_alloconly_create("message parser", 10240);
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen input = test_istream_create(input_msg);
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen parser = message_parser_init(pool, input, 0, 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen test_assert(ret < 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch message_parser_deinit(&parser, &parts);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen test_assert(parts->header_size.lines == 2);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->header_size.physical_size == 45);
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainen test_assert(parts->header_size.virtual_size == 45+2);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->body_size.lines == 7);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->body_size.physical_size == 86);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->body_size.virtual_size == 86+7);
858a13d06402d3d6e2dc683f6696c14192ad6b02Stephan Bosch test_assert(parts->children->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->physical_pos == 49);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->header_size.lines == 2);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->header_size.physical_size == 46);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->header_size.virtual_size == 46+2);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->body_size.lines == 4);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->body_size.physical_size == 36);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->body_size.virtual_size == 36+4);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->children->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME));
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(parts->children->children->physical_pos == 100);
ccd968b44a40b9c2cf6278fabfa2a80cc5d9e46bTimo Sirainen test_assert(parts->children->children->header_size.lines == 2);
ccd968b44a40b9c2cf6278fabfa2a80cc5d9e46bTimo Sirainen test_assert(parts->children->children->header_size.physical_size == 26);
ccd968b44a40b9c2cf6278fabfa2a80cc5d9e46bTimo Sirainen test_assert(parts->children->children->header_size.virtual_size == 26+2);
ccd968b44a40b9c2cf6278fabfa2a80cc5d9e46bTimo Sirainen test_assert(parts->children->children->body_size.lines == 1);
ccd968b44a40b9c2cf6278fabfa2a80cc5d9e46bTimo Sirainen test_assert(parts->children->children->body_size.physical_size == 5);
ccd968b44a40b9c2cf6278fabfa2a80cc5d9e46bTimo Sirainen test_assert(parts->children->children->body_size.virtual_size == 5+1);
ccd968b44a40b9c2cf6278fabfa2a80cc5d9e46bTimo Sirainen
ccd968b44a40b9c2cf6278fabfa2a80cc5d9e46bTimo Sirainen test_parsed_parts(input, parts);
ccd968b44a40b9c2cf6278fabfa2a80cc5d9e46bTimo Sirainen i_stream_unref(&input);
ccd968b44a40b9c2cf6278fabfa2a80cc5d9e46bTimo Sirainen pool_unref(&pool);
ccd968b44a40b9c2cf6278fabfa2a80cc5d9e46bTimo Sirainen test_end();
6c768e0e1ca2da178e79f7435c32ced01f6bcb24Timo Sirainen}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic void test_message_parser_continuing_truncated_mime_boundary(void)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
6c768e0e1ca2da178e79f7435c32ced01f6bcb24Timo Sirainenstatic const char input_msg[] =
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"Content-Type: multipart/mixed; boundary=\"a\"\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"--a\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"Content-Type: multipart/mixed; boundary=\"ab\"\n"
6c768e0e1ca2da178e79f7435c32ced01f6bcb24Timo Sirainen"MIME-Version: 1.0\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch"--ab\n"
6c768e0e1ca2da178e79f7435c32ced01f6bcb24Timo Sirainen"Content-Type: text/plain\n"
6c768e0e1ca2da178e79f7435c32ced01f6bcb24Timo Sirainen"\n"
6c768e0e1ca2da178e79f7435c32ced01f6bcb24Timo Sirainen"--ab--\n"
6c768e0e1ca2da178e79f7435c32ced01f6bcb24Timo Sirainen"--a--\n\n";
6c768e0e1ca2da178e79f7435c32ced01f6bcb24Timo Sirainen struct message_parser_ctx *parser;
6c6915f4d75c352c63156df202fa51cd97524babStephan Bosch struct istream *input;
6c6915f4d75c352c63156df202fa51cd97524babStephan Bosch struct message_part *parts, *part;
6c6915f4d75c352c63156df202fa51cd97524babStephan Bosch struct message_block block;
6c6915f4d75c352c63156df202fa51cd97524babStephan Bosch pool_t pool;
6c768e0e1ca2da178e79f7435c32ced01f6bcb24Timo Sirainen int ret;
6c768e0e1ca2da178e79f7435c32ced01f6bcb24Timo Sirainen
6c768e0e1ca2da178e79f7435c32ced01f6bcb24Timo Sirainen test_begin("message parser continuing truncated mime boundary");
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch pool = pool_alloconly_create("message parser", 10240);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch input = test_istream_create(input_msg);
50d1446e71cfbdc5b6d7bafcf91b7bff453989d3Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch parser = message_parser_init(pool, input, 0, 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(ret < 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch message_parser_deinit(&parser, &parts);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
50d1446e71cfbdc5b6d7bafcf91b7bff453989d3Stephan Bosch part = parts;
50d1446e71cfbdc5b6d7bafcf91b7bff453989d3Stephan Bosch test_assert(part->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(part->header_size.lines == 2);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(part->header_size.physical_size == 45);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(part->header_size.virtual_size == 45+2);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(part->body_size.lines == 9);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(part->body_size.physical_size == 112);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(part->body_size.virtual_size == 112+9);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
e8f1e510df3ab051a816715c2056f0d10aee929eStephan Bosch part = parts->children;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(part->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
6c6915f4d75c352c63156df202fa51cd97524babStephan Bosch test_assert(part->physical_pos == 49);
6c6915f4d75c352c63156df202fa51cd97524babStephan Bosch test_assert(part->header_size.lines == 1);
6c6915f4d75c352c63156df202fa51cd97524babStephan Bosch test_assert(part->header_size.physical_size == 45+17);
6c6915f4d75c352c63156df202fa51cd97524babStephan Bosch test_assert(part->header_size.virtual_size == 45+17+1);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(part->body_size.lines == 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(part->body_size.physical_size == 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(part->children == NULL);
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen /* this will not be a child, since the header was truncated. I guess
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen we could make it, but it would complicate the message-parser even
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen more. */
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen part = parts->children->next;
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen test_assert(part->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME));
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen test_assert(part->physical_pos == 117);
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen test_assert(part->header_size.lines == 1);
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen test_assert(part->header_size.physical_size == 25);
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen test_assert(part->header_size.virtual_size == 25+1);
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen test_assert(part->body_size.lines == 0);
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen test_assert(part->body_size.physical_size == 0);
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen test_assert(part->children == NULL);
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen part = parts->children->next->next;
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen test_assert(part->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME));
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen test_assert(part->header_size.lines == 0);
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen test_assert(part->header_size.physical_size == 0);
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen test_assert(part->body_size.lines == 0);
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen test_assert(part->body_size.physical_size == 0);
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen test_assert(part->children == NULL);
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen test_assert(part->next == NULL);
c6494255de7b934281dd052960fd8ab5aa48e79eTimo Sirainen
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen test_parsed_parts(input, parts);
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen i_stream_unref(&input);
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen pool_unref(&pool);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_end();
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
50d1446e71cfbdc5b6d7bafcf91b7bff453989d3Stephan Boschstatic void test_message_parser_no_eoh(void)
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen{
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen static const char input_msg[] = "a:b\n";
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen struct message_parser_ctx *parser;
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen struct istream *input;
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen struct message_part *parts;
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen struct message_block block;
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen pool_t pool;
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen test_begin("message parser no EOH");
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen pool = pool_alloconly_create("message parser", 10240);
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen input = test_istream_create(input_msg);
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen parser = message_parser_init(pool, input, 0, 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(message_parser_parse_next_block(parser, &block) > 0 &&
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch block.hdr != NULL && strcmp(block.hdr->name, "a") == 0 &&
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch block.hdr->value_len == 1 && block.hdr->value[0] == 'b');
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(message_parser_parse_next_block(parser, &block) > 0 &&
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch block.hdr == NULL && block.size == 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_assert(message_parser_parse_next_block(parser, &block) < 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch message_parser_deinit(&parser, &parts);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_parsed_parts(input, parts);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch i_stream_unref(&input);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch pool_unref(&pool);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_end();
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschint main(void)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch static void (*const test_functions[])(void) = {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_message_parser_small_blocks,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_message_parser_truncated_mime_headers,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_message_parser_truncated_mime_headers2,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_message_parser_truncated_mime_headers3,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_message_parser_empty_multipart,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_message_parser_duplicate_mime_boundary,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_message_parser_garbage_suffix_mime_boundary,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_message_parser_continuing_mime_boundary,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch test_message_parser_continuing_truncated_mime_boundary,
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch test_message_parser_no_eoh,
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch NULL
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch };
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return test_run(test_functions);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch