bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen#include "lib.h"
498eecf19b1b408d5321cb048697744d7cee90b2Timo Sirainen#include "str.h"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen#include "istream.h"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen#include "message-parser.h"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen#include "test-common.h"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainenstatic const char test_msg[] =
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"Return-Path: <test@example.org>\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"Subject: Hello world\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"From: Test User <test@example.org>\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"To: Another User <test2@example.org>\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"Message-Id: <1.2.3.4@example>\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"Mime-Version: 1.0\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"Date: Sun, 23 May 2007 04:58:08 +0300\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"Content-Type: multipart/signed; micalg=pgp-sha1;\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen" protocol=\"application/pgp-signature\";\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen" boundary=\"=-GNQXLhuj24Pl1aCkk4/d\"\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"--=-GNQXLhuj24Pl1aCkk4/d\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"Content-Type: text/plain\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"Content-Transfer-Encoding: quoted-printable\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"There was a day=20\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"a happy=20day\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"--=-GNQXLhuj24Pl1aCkk4/d\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"Content-Type: application/pgp-signature; name=signature.asc\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"-----BEGIN PGP SIGNATURE-----\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"Version: GnuPG v1.2.4 (GNU/Linux)\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"invalid\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"-----END PGP SIGNATURE-----\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"--=-GNQXLhuj24Pl1aCkk4/d--\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"\n"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen"\n";
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen#define TEST_MSG_LEN (sizeof(test_msg)-1)
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainenstatic bool msg_parts_cmp(struct message_part *p1, struct message_part *p2)
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen{
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen while (p1 != NULL || p2 != NULL) {
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen if ((p1 != NULL) != (p2 != NULL))
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen return FALSE;
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen if ((p1->children != NULL) != (p2->children != NULL))
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen return FALSE;
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
23bdbb7b1831785c6ba6df190f6369da882d2b9dTimo Sirainen if (p1->children != NULL) {
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen if (!msg_parts_cmp(p1->children, p2->children))
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen return FALSE;
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen }
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen if (p1->physical_pos != p2->physical_pos ||
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen p1->header_size.physical_size != p2->header_size.physical_size ||
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen p1->header_size.virtual_size != p2->header_size.virtual_size ||
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen p1->header_size.lines != p2->header_size.lines ||
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen p1->body_size.physical_size != p2->body_size.physical_size ||
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen p1->body_size.virtual_size != p2->body_size.virtual_size ||
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen p1->body_size.lines != p2->body_size.lines ||
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen p1->flags != p2->flags)
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen return FALSE;
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen p1 = p1->next;
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen p2 = p2->next;
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen }
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen return TRUE;
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen}
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainenstatic void test_parsed_parts(struct istream *input, struct message_part *parts)
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen{
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen struct message_parser_ctx *parser;
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen struct message_block block;
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen struct message_part *parts2;
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen uoff_t i, input_size;
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen const char *error;
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen int ret;
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen i_stream_seek(input, 0);
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen if (i_stream_get_size(input, TRUE, &input_size) < 0)
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen i_unreached();
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen parser = message_parser_init_from_parts(parts, input, 0,
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK);
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen for (i = 1; i <= input_size*2+1; i++) {
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_istream_set_size(input, i/2);
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen if (i > TEST_MSG_LEN*2)
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_istream_set_allow_eof(input, TRUE);
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen while ((ret = message_parser_parse_next_block(parser,
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen &block)) > 0) ;
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen }
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_assert(message_parser_deinit_from_parts(&parser, &parts2, &error) == 0);
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_assert(msg_parts_cmp(parts, parts2));
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen}
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainenstatic void test_message_parser_small_blocks(void)
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen{
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen struct message_parser_ctx *parser;
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen struct istream *input;
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen struct message_part *parts, *parts2;
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen struct message_block block;
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen unsigned int i, end_of_headers_idx;
498eecf19b1b408d5321cb048697744d7cee90b2Timo Sirainen string_t *output;
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen pool_t pool;
12e5ac049bd74f8b98d9dc62adcb0bf3217beef6Martti Rannanjärvi const char *error;
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen int ret;
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen test_begin("message parser in small blocks");
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen pool = pool_alloconly_create("message parser", 10240);
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen input = test_istream_create(test_msg);
498eecf19b1b408d5321cb048697744d7cee90b2Timo Sirainen output = t_str_new(128);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen /* full parsing */
498eecf19b1b408d5321cb048697744d7cee90b2Timo Sirainen parser = message_parser_init(pool, input, 0,
498eecf19b1b408d5321cb048697744d7cee90b2Timo Sirainen MESSAGE_PARSER_FLAG_INCLUDE_MULTIPART_BLOCKS |
498eecf19b1b408d5321cb048697744d7cee90b2Timo Sirainen MESSAGE_PARSER_FLAG_INCLUDE_BOUNDARIES);
498eecf19b1b408d5321cb048697744d7cee90b2Timo Sirainen while ((ret = message_parser_parse_next_block(parser, &block)) > 0) {
498eecf19b1b408d5321cb048697744d7cee90b2Timo Sirainen if (block.hdr != NULL)
498eecf19b1b408d5321cb048697744d7cee90b2Timo Sirainen message_header_line_write(output, block.hdr);
d4488f314d0c799c5f5b8a7890e17eef868f7a2cMartti Rannanjärvi else if (block.size > 0)
498eecf19b1b408d5321cb048697744d7cee90b2Timo Sirainen str_append_n(output, block.data, block.size);
498eecf19b1b408d5321cb048697744d7cee90b2Timo Sirainen }
498eecf19b1b408d5321cb048697744d7cee90b2Timo Sirainen
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen test_assert(ret < 0);
12e5ac049bd74f8b98d9dc62adcb0bf3217beef6Martti Rannanjärvi message_parser_deinit(&parser, &parts);
498eecf19b1b408d5321cb048697744d7cee90b2Timo Sirainen test_assert(strcmp(test_msg, str_c(output)) == 0);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen /* parsing in small blocks */
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen i_stream_seek(input, 0);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen test_istream_set_allow_eof(input, FALSE);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen parser = message_parser_init(pool, input, 0, 0);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen for (i = 1; i <= TEST_MSG_LEN*2+1; i++) {
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen test_istream_set_size(input, i/2);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen if (i > TEST_MSG_LEN*2)
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen test_istream_set_allow_eof(input, TRUE);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen while ((ret = message_parser_parse_next_block(parser,
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen &block)) > 0) ;
5f237cf1915127fe143ac4c1d3cb4d1139f3b97dTimo Sirainen test_assert((ret == 0 && i <= TEST_MSG_LEN*2) ||
5f237cf1915127fe143ac4c1d3cb4d1139f3b97dTimo Sirainen (ret < 0 && i > TEST_MSG_LEN*2));
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen }
12e5ac049bd74f8b98d9dc62adcb0bf3217beef6Martti Rannanjärvi message_parser_deinit(&parser, &parts2);
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen test_assert(msg_parts_cmp(parts, parts2));
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen /* parsing in small blocks from preparsed parts */
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen i_stream_seek(input, 0);
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen test_istream_set_allow_eof(input, FALSE);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
5f237cf1915127fe143ac4c1d3cb4d1139f3b97dTimo Sirainen end_of_headers_idx = (strstr(test_msg, "\n-----") - test_msg);
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen parser = message_parser_init_from_parts(parts, input, 0,
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK);
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen for (i = 1; i <= TEST_MSG_LEN*2+1; i++) {
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen test_istream_set_size(input, i/2);
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen if (i > TEST_MSG_LEN*2)
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen test_istream_set_allow_eof(input, TRUE);
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen while ((ret = message_parser_parse_next_block(parser,
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen &block)) > 0) ;
5f237cf1915127fe143ac4c1d3cb4d1139f3b97dTimo Sirainen test_assert((ret == 0 && i/2 <= end_of_headers_idx) ||
5f237cf1915127fe143ac4c1d3cb4d1139f3b97dTimo Sirainen (ret < 0 && i/2 > end_of_headers_idx));
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen }
12e5ac049bd74f8b98d9dc62adcb0bf3217beef6Martti Rannanjärvi test_assert(message_parser_deinit_from_parts(&parser, &parts2, &error) == 0);
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen test_assert(msg_parts_cmp(parts, parts2));
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen i_stream_unref(&input);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen pool_unref(&pool);
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen test_end();
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen}
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainenstatic void test_message_parser_truncated_mime_headers(void)
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen{
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainenstatic const char input_msg[] =
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen"Content-Type: multipart/mixed; boundary=\":foo\"\n"
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen"\n"
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen"--:foo\n"
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen"--:foo\n"
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen"Content-Type: text/plain\n"
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen"--:foo\n"
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen"Content-Type: text/plain\r\n"
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen"--:foo\n"
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen"Content-Type: text/html\n"
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen"--:foo--\n";
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen struct message_parser_ctx *parser;
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen struct istream *input;
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen struct message_part *parts, *part;
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen struct message_block block;
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen pool_t pool;
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen int ret;
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen test_begin("message parser truncated mime headers");
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen pool = pool_alloconly_create("message parser", 10240);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen input = test_istream_create(input_msg);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen parser = message_parser_init(pool, input, 0, 0);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen test_assert(ret < 0);
12e5ac049bd74f8b98d9dc62adcb0bf3217beef6Martti Rannanjärvi message_parser_deinit(&parser, &parts);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen test_assert((parts->flags & MESSAGE_PART_FLAG_MULTIPART) != 0);
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_assert(parts->header_size.lines == 2);
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_assert(parts->header_size.physical_size == 48);
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_assert(parts->header_size.virtual_size == 48+2);
f148466c7b648669b99bf20c651ae7fc81d28659Timo Sirainen test_assert(parts->body_size.lines == 8);
f148466c7b648669b99bf20c651ae7fc81d28659Timo Sirainen test_assert(parts->body_size.physical_size == 112);
f148466c7b648669b99bf20c651ae7fc81d28659Timo Sirainen test_assert(parts->body_size.virtual_size == 112+7);
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_assert(parts->children->physical_pos == 55);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen test_assert(parts->children->header_size.physical_size == 0);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen test_assert(parts->children->body_size.physical_size == 0);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen test_assert(parts->children->body_size.lines == 0);
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_assert(parts->children->next->physical_pos == 62);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen test_assert(parts->children->next->header_size.physical_size == 24);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen test_assert(parts->children->next->header_size.virtual_size == 24);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen test_assert(parts->children->next->header_size.lines == 0);
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_assert(parts->children->next->next->physical_pos == 94);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen test_assert(parts->children->next->next->header_size.physical_size == 24);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen test_assert(parts->children->next->next->header_size.virtual_size == 24);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen test_assert(parts->children->next->next->header_size.lines == 0);
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_assert(parts->children->next->next->next->physical_pos == 127);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen test_assert(parts->children->next->next->next->header_size.physical_size == 23);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen test_assert(parts->children->next->next->next->header_size.virtual_size == 23);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen test_assert(parts->children->next->next->next->header_size.lines == 0);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen for (part = parts->children; part != NULL; part = part->next) {
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen test_assert(part->body_size.physical_size == 0);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen test_assert(part->body_size.virtual_size == 0);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen }
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen test_assert(parts->children->next->next->next->next == NULL);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_parsed_parts(input, parts);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen i_stream_unref(&input);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen pool_unref(&pool);
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen test_end();
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen}
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainenstatic void test_message_parser_truncated_mime_headers2(void)
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen{
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainenstatic const char input_msg[] =
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen"Content-Type: multipart/mixed; boundary=\"ab\"\n"
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen"\n"
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen"--ab\n"
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen"Content-Type: multipart/mixed; boundary=\"a\"\n"
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen"\n"
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen"--ab\n"
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen"Content-Type: text/plain\n"
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen"\n"
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen"--a\n\n";
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen struct message_parser_ctx *parser;
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen struct istream *input;
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen struct message_part *parts;
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen struct message_block block;
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen pool_t pool;
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen int ret;
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_begin("message parser truncated mime headers 2");
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen pool = pool_alloconly_create("message parser", 10240);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen input = test_istream_create(input_msg);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen parser = message_parser_init(pool, input, 0, 0);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(ret < 0);
12e5ac049bd74f8b98d9dc62adcb0bf3217beef6Martti Rannanjärvi message_parser_deinit(&parser, &parts);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->header_size.lines == 2);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->header_size.physical_size == 46);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->header_size.virtual_size == 46+2);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->body_size.lines == 8);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->body_size.physical_size == 86);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->body_size.virtual_size == 86+8);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->children->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->children->physical_pos == 51);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->children->header_size.lines == 1);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->children->header_size.physical_size == 44);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->children->header_size.virtual_size == 44+1);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->children->body_size.lines == 0);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->children->body_size.physical_size == 0);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->children->children == NULL);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->children->next->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME));
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->children->next->physical_pos == 101);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->children->next->header_size.lines == 2);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->children->next->header_size.physical_size == 26);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->children->next->header_size.virtual_size == 26+2);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->children->next->body_size.lines == 2);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->children->next->body_size.physical_size == 5);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->children->next->body_size.virtual_size == 5+2);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->children->next->children == NULL);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_parsed_parts(input, parts);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen i_stream_unref(&input);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen pool_unref(&pool);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_end();
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen}
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainenstatic void test_message_parser_truncated_mime_headers3(void)
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen{
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainenstatic const char input_msg[] =
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen"Content-Type: multipart/mixed; boundary=\"ab\"\n";
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen struct message_parser_ctx *parser;
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen struct istream *input;
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen struct message_part *parts;
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen struct message_block block;
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen pool_t pool;
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen int ret;
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_begin("message parser truncated mime headers 3");
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen pool = pool_alloconly_create("message parser", 10240);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen input = test_istream_create(input_msg);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen parser = message_parser_init(pool, input, 0, 0);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(ret < 0);
12e5ac049bd74f8b98d9dc62adcb0bf3217beef6Martti Rannanjärvi message_parser_deinit(&parser, &parts);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->header_size.lines == 1);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->header_size.physical_size == 45);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->header_size.virtual_size == 45+1);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->body_size.lines == 0);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->body_size.physical_size == 0);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_assert(parts->children == NULL);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_parsed_parts(input, parts);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen i_stream_unref(&input);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen pool_unref(&pool);
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_end();
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen}
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainenstatic void test_message_parser_empty_multipart(void)
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen{
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainenstatic const char input_msg[] =
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen"Content-Type: multipart/mixed; boundary=\"ab\"\n"
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen"\n"
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen"body\n";
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen struct message_parser_ctx *parser;
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen struct istream *input;
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen struct message_part *parts;
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen struct message_block block;
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen pool_t pool;
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen int ret;
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_begin("message parser empty multipart");
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen pool = pool_alloconly_create("message parser", 10240);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen input = test_istream_create(input_msg);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen parser = message_parser_init(pool, input, 0, 0);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(ret < 0);
12e5ac049bd74f8b98d9dc62adcb0bf3217beef6Martti Rannanjärvi message_parser_deinit(&parser, &parts);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->header_size.lines == 2);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->header_size.physical_size == 46);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->header_size.virtual_size == 46+2);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->body_size.lines == 1);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->body_size.physical_size == 5);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->body_size.virtual_size == 5+1);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->children == NULL);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_parsed_parts(input, parts);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen i_stream_unref(&input);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen pool_unref(&pool);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_end();
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen}
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainenstatic void test_message_parser_duplicate_mime_boundary(void)
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen{
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainenstatic const char input_msg[] =
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen"Content-Type: multipart/mixed; boundary=\"a\"\n"
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen"\n"
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen"--a\n"
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen"Content-Type: multipart/mixed; boundary=\"a\"\n"
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen"\n"
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen"--a\n"
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen"Content-Type: text/plain\n"
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen"\n"
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen"body\n";
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen struct message_parser_ctx *parser;
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen struct istream *input;
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen struct message_part *parts;
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen struct message_block block;
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen pool_t pool;
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen int ret;
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_begin("message parser duplicate mime boundary");
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen pool = pool_alloconly_create("message parser", 10240);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen input = test_istream_create(input_msg);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen parser = message_parser_init(pool, input, 0, 0);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(ret < 0);
12e5ac049bd74f8b98d9dc62adcb0bf3217beef6Martti Rannanjärvi message_parser_deinit(&parser, &parts);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->header_size.lines == 2);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->header_size.physical_size == 45);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->header_size.virtual_size == 45+2);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->body_size.lines == 7);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->body_size.physical_size == 84);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->body_size.virtual_size == 84+7);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->physical_pos == 49);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->header_size.lines == 2);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->header_size.physical_size == 45);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->header_size.virtual_size == 45+2);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->body_size.lines == 4);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->body_size.physical_size == 35);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->body_size.virtual_size == 35+4);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->children->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME));
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->children->physical_pos == 98);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->children->header_size.lines == 2);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->children->header_size.physical_size == 26);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->children->header_size.virtual_size == 26+2);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->children->body_size.lines == 1);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->children->body_size.physical_size == 5);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->children->body_size.virtual_size == 5+1);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_parsed_parts(input, parts);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen i_stream_unref(&input);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen pool_unref(&pool);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_end();
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen}
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainenstatic void test_message_parser_garbage_suffix_mime_boundary(void)
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen{
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainenstatic const char input_msg[] =
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen"Content-Type: multipart/mixed; boundary=\"a\"\n"
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen"\n"
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen"--ab\n"
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen"Content-Type: multipart/mixed; boundary=\"a\"\n"
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen"\n"
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen"--ac\n"
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen"Content-Type: text/plain\n"
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen"\n"
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen"body\n";
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen struct message_parser_ctx *parser;
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen struct istream *input;
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen struct message_part *parts;
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen struct message_block block;
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen pool_t pool;
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen int ret;
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_begin("message parser garbage suffix mime boundary");
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen pool = pool_alloconly_create("message parser", 10240);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen input = test_istream_create(input_msg);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen parser = message_parser_init(pool, input, 0, 0);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(ret < 0);
12e5ac049bd74f8b98d9dc62adcb0bf3217beef6Martti Rannanjärvi message_parser_deinit(&parser, &parts);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->header_size.lines == 2);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->header_size.physical_size == 45);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->header_size.virtual_size == 45+2);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->body_size.lines == 7);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->body_size.physical_size == 86);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->body_size.virtual_size == 86+7);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->children->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->children->physical_pos == 50);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->children->header_size.lines == 2);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->children->header_size.physical_size == 45);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->children->header_size.virtual_size == 45+2);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->children->body_size.lines == 4);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->children->body_size.physical_size == 36);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->children->body_size.virtual_size == 36+4);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->children->children->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME));
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->children->children->physical_pos == 100);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->children->children->header_size.lines == 2);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->children->children->header_size.physical_size == 26);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->children->children->header_size.virtual_size == 26+2);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->children->children->body_size.lines == 1);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->children->children->body_size.physical_size == 5);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_assert(parts->children->children->body_size.virtual_size == 5+1);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_parsed_parts(input, parts);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen i_stream_unref(&input);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen pool_unref(&pool);
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_end();
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen}
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainenstatic void test_message_parser_continuing_mime_boundary(void)
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen{
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainenstatic const char input_msg[] =
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen"Content-Type: multipart/mixed; boundary=\"a\"\n"
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen"\n"
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen"--a\n"
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen"Content-Type: multipart/mixed; boundary=\"ab\"\n"
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen"\n"
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen"--ab\n"
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen"Content-Type: text/plain\n"
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen"\n"
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen"body\n";
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen struct message_parser_ctx *parser;
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen struct istream *input;
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen struct message_part *parts;
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen struct message_block block;
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen pool_t pool;
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen int ret;
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_begin("message parser continuing mime boundary");
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen pool = pool_alloconly_create("message parser", 10240);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen input = test_istream_create(input_msg);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen parser = message_parser_init(pool, input, 0, 0);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(ret < 0);
12e5ac049bd74f8b98d9dc62adcb0bf3217beef6Martti Rannanjärvi message_parser_deinit(&parser, &parts);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->header_size.lines == 2);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->header_size.physical_size == 45);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->header_size.virtual_size == 45+2);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->body_size.lines == 7);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->body_size.physical_size == 86);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->body_size.virtual_size == 86+7);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->physical_pos == 49);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->header_size.lines == 2);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->header_size.physical_size == 46);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->header_size.virtual_size == 46+2);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->body_size.lines == 4);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->body_size.physical_size == 36);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->body_size.virtual_size == 36+4);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->children->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME));
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->children->physical_pos == 100);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->children->header_size.lines == 2);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->children->header_size.physical_size == 26);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->children->header_size.virtual_size == 26+2);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->children->body_size.lines == 1);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->children->body_size.physical_size == 5);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_assert(parts->children->children->body_size.virtual_size == 5+1);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_parsed_parts(input, parts);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen i_stream_unref(&input);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen pool_unref(&pool);
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_end();
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen}
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainenstatic void test_message_parser_continuing_truncated_mime_boundary(void)
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen{
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainenstatic const char input_msg[] =
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen"Content-Type: multipart/mixed; boundary=\"a\"\n"
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen"\n"
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen"--a\n"
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen"Content-Type: multipart/mixed; boundary=\"ab\"\n"
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen"MIME-Version: 1.0\n"
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen"--ab\n"
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen"Content-Type: text/plain\n"
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen"\n"
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen"--ab--\n"
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen"--a--\n\n";
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen struct message_parser_ctx *parser;
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen struct istream *input;
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen struct message_part *parts, *part;
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen struct message_block block;
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen pool_t pool;
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen int ret;
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_begin("message parser continuing truncated mime boundary");
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen pool = pool_alloconly_create("message parser", 10240);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen input = test_istream_create(input_msg);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen parser = message_parser_init(pool, input, 0, 0);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(ret < 0);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen message_parser_deinit(&parser, &parts);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen part = parts;
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->header_size.lines == 2);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->header_size.physical_size == 45);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->header_size.virtual_size == 45+2);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->body_size.lines == 9);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->body_size.physical_size == 112);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->body_size.virtual_size == 112+9);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen part = parts->children;
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->physical_pos == 49);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->header_size.lines == 1);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->header_size.physical_size == 45+17);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->header_size.virtual_size == 45+17+1);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->body_size.lines == 0);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->body_size.physical_size == 0);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->children == NULL);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen /* this will not be a child, since the header was truncated. I guess
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen we could make it, but it would complicate the message-parser even
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen more. */
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen part = parts->children->next;
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME));
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->physical_pos == 117);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->header_size.lines == 1);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->header_size.physical_size == 25);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->header_size.virtual_size == 25+1);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->body_size.lines == 0);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->body_size.physical_size == 0);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->children == NULL);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen part = parts->children->next->next;
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME));
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->header_size.lines == 0);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->header_size.physical_size == 0);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->body_size.lines == 0);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->body_size.physical_size == 0);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->children == NULL);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_assert(part->next == NULL);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_parsed_parts(input, parts);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen i_stream_unref(&input);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen pool_unref(&pool);
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_end();
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen}
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainenstatic void test_message_parser_no_eoh(void)
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen{
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen static const char input_msg[] = "a:b\n";
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen struct message_parser_ctx *parser;
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen struct istream *input;
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen struct message_part *parts;
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen struct message_block block;
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen pool_t pool;
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen test_begin("message parser no EOH");
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen pool = pool_alloconly_create("message parser", 10240);
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen input = test_istream_create(input_msg);
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen parser = message_parser_init(pool, input, 0, 0);
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen test_assert(message_parser_parse_next_block(parser, &block) > 0 &&
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen block.hdr != NULL && strcmp(block.hdr->name, "a") == 0 &&
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen block.hdr->value_len == 1 && block.hdr->value[0] == 'b');
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen test_assert(message_parser_parse_next_block(parser, &block) > 0 &&
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen block.hdr == NULL && block.size == 0);
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen test_assert(message_parser_parse_next_block(parser, &block) < 0);
12e5ac049bd74f8b98d9dc62adcb0bf3217beef6Martti Rannanjärvi message_parser_deinit(&parser, &parts);
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen
aeaf818613081b9a9ff8c9fd4306e8dbfab4fd86Timo Sirainen test_parsed_parts(input, parts);
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen i_stream_unref(&input);
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen pool_unref(&pool);
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen test_end();
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen}
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainenint main(void)
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen{
baf3e87e186453fda13bd21f7cbcb2efc8492e8bTimo Sirainen static void (*const test_functions[])(void) = {
11d72d764c104b4f1a8c44ec8a5fee420517645bTimo Sirainen test_message_parser_small_blocks,
7d800c558b4a40f11748d4ebfc2bf89eb743f03cTimo Sirainen test_message_parser_truncated_mime_headers,
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_message_parser_truncated_mime_headers2,
6df4a174b4cbdc439ed435a0cdc71d4a0126d54aTimo Sirainen test_message_parser_truncated_mime_headers3,
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_message_parser_empty_multipart,
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_message_parser_duplicate_mime_boundary,
7195d775e5e943af90d24a615847c733a104e3d4Timo Sirainen test_message_parser_garbage_suffix_mime_boundary,
7a12331c6360968b141a0888e0bf04dd24145f23Timo Sirainen test_message_parser_continuing_mime_boundary,
12fd7a30563f3256642070ef9528dda0d089cb41Timo Sirainen test_message_parser_continuing_truncated_mime_boundary,
a4392e9d312e3b5973fe5dbaee7028197a700ff0Timo Sirainen test_message_parser_no_eoh,
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen NULL
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen };
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen return test_run(test_functions);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen}