test-message-parser.c revision 12e5ac049bd74f8b98d9dc62adcb0bf3217beef6
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2007-2016 Dovecot authors, see the included COPYING file */
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#include "str.h"
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen#include "istream.h"
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen#include "message-parser.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "test-common.h"
5666a3d6a7ea89362b8d9e8b39b15424cd9d6388Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic const char test_msg[] =
146f9076cd456ea1e9b3f8536456d9d3c962fadbStephan Bosch"Return-Path: <test@example.org>\n"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen"Subject: Hello world\n"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen"From: Test User <test@example.org>\n"
8c909e451d14075c05d90382cf8eebc4e354f569Timo Sirainen"To: Another User <test2@example.org>\n"
8c909e451d14075c05d90382cf8eebc4e354f569Timo Sirainen"Message-Id: <1.2.3.4@example>\n"
8c909e451d14075c05d90382cf8eebc4e354f569Timo Sirainen"Mime-Version: 1.0\n"
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen"Date: Sun, 23 May 2007 04:58:08 +0300\n"
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen"Content-Type: multipart/signed; micalg=pgp-sha1;\n"
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen" protocol=\"application/pgp-signature\";\n"
3ed2d0f6b5e67e2663d44489d9da3176823789a8Timo Sirainen" boundary=\"=-GNQXLhuj24Pl1aCkk4/d\"\n"
65f8fb656051f1059f7b5a2da9c5555adcc30439Timo Sirainen"\n"
1a5573ebc32fae2fe576ec544e1781323c1db609Timo Sirainen"--=-GNQXLhuj24Pl1aCkk4/d\n"
1a5573ebc32fae2fe576ec544e1781323c1db609Timo Sirainen"Content-Type: text/plain\n"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen"Content-Transfer-Encoding: quoted-printable\n"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen"\n"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen"There was a day=20\n"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen"a happy=20day\n"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen"\n"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen"--=-GNQXLhuj24Pl1aCkk4/d\n"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen"Content-Type: application/pgp-signature; name=signature.asc\n"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen"\n"
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen"-----BEGIN PGP SIGNATURE-----\n"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen"Version: GnuPG v1.2.4 (GNU/Linux)\n"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen"\n"
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen"invalid\n"
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen"-----END PGP SIGNATURE-----\n"
2dd39e478269d6fb0bb26d12b394aa30ee965e38Timo Sirainen"\n"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen"--=-GNQXLhuj24Pl1aCkk4/d--\n"
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen"\n"
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen"\n";
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#define TEST_MSG_LEN (sizeof(test_msg)-1)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstatic bool msg_parts_cmp(struct message_part *p1, struct message_part *p2)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen{
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen while (p1 != NULL || p2 != NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if ((p1 != NULL) != (p2 != NULL))
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen return FALSE;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen if ((p1->children != NULL) != (p2->children != NULL))
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen return FALSE;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
3e564425db51f3921ce4de11859777135fdedd15Timo Sirainen if (p1->children) {
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen if (!msg_parts_cmp(p1->children, p2->children))
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen return FALSE;
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen }
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen if (p1->physical_pos != p2->physical_pos ||
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen p1->header_size.physical_size != p2->header_size.physical_size ||
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen p1->header_size.virtual_size != p2->header_size.virtual_size ||
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen p1->header_size.lines != p2->header_size.lines ||
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen p1->body_size.physical_size != p2->body_size.physical_size ||
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen p1->body_size.virtual_size != p2->body_size.virtual_size ||
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen p1->body_size.lines != p2->body_size.lines ||
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen p1->flags != p2->flags)
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen return FALSE;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen p1 = p1->next;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen p2 = p2->next;
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen }
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen return TRUE;
4ba9a1d3facc515b3feb5238a16bcf91f76fac61Timo Sirainen}
4ba9a1d3facc515b3feb5238a16bcf91f76fac61Timo Sirainen
dfaefeabae939803ceb8c503101e86b5496541d1Timo Sirainenstatic void test_message_parser_small_blocks(void)
dfaefeabae939803ceb8c503101e86b5496541d1Timo Sirainen{
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen struct message_parser_ctx *parser;
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen struct istream *input;
8b31f966d9688e07672ef1958dcbdb7686523c04Timo Sirainen struct message_part *parts, *parts2;
8b31f966d9688e07672ef1958dcbdb7686523c04Timo Sirainen struct message_block block;
9847ec56efa15fa063eea9988eee2d4ed9ec7d58Timo Sirainen unsigned int i, end_of_headers_idx;
9847ec56efa15fa063eea9988eee2d4ed9ec7d58Timo Sirainen string_t *output;
9847ec56efa15fa063eea9988eee2d4ed9ec7d58Timo Sirainen pool_t pool;
d46a1e3f999dda802dc5137e883adcd7a6629cd3Timo Sirainen const char *error;
d46a1e3f999dda802dc5137e883adcd7a6629cd3Timo Sirainen int ret;
d46a1e3f999dda802dc5137e883adcd7a6629cd3Timo Sirainen
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen test_begin("message parser in small blocks");
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen pool = pool_alloconly_create("message parser", 10240);
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen input = test_istream_create(test_msg);
291ce16fffca75e8598a8c9dceb08613413dcb07Timo Sirainen output = t_str_new(128);
291ce16fffca75e8598a8c9dceb08613413dcb07Timo Sirainen
291ce16fffca75e8598a8c9dceb08613413dcb07Timo Sirainen /* full parsing */
08e9fd42eb8007e1f9db62c088eef74f906114a5Josef 'Jeff' Sipek parser = message_parser_init(pool, input, 0,
08e9fd42eb8007e1f9db62c088eef74f906114a5Josef 'Jeff' Sipek MESSAGE_PARSER_FLAG_INCLUDE_MULTIPART_BLOCKS |
08e9fd42eb8007e1f9db62c088eef74f906114a5Josef 'Jeff' Sipek MESSAGE_PARSER_FLAG_INCLUDE_BOUNDARIES);
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen while ((ret = message_parser_parse_next_block(parser, &block)) > 0) {
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen if (block.hdr != NULL)
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen message_header_line_write(output, block.hdr);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen else
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen str_append_n(output, block.data, block.size);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen }
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen test_assert(ret < 0);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen message_parser_deinit(&parser, &parts);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen test_assert(strcmp(test_msg, str_c(output)) == 0);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen /* parsing in small blocks */
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen i_stream_seek(input, 0);
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen test_istream_set_allow_eof(input, FALSE);
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen parser = message_parser_init(pool, input, 0, 0);
30d50c7e8706f2d750215e009504109ca19cd485Timo Sirainen for (i = 1; i <= TEST_MSG_LEN*2+1; i++) {
30d50c7e8706f2d750215e009504109ca19cd485Timo Sirainen test_istream_set_size(input, i/2);
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen if (i > TEST_MSG_LEN*2)
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen test_istream_set_allow_eof(input, TRUE);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen while ((ret = message_parser_parse_next_block(parser,
57a8c6a95e4bce3eeaba36985adb81c07dd683ffTimo Sirainen &block)) > 0) ;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen test_assert((ret == 0 && i <= TEST_MSG_LEN*2) ||
afe1da042382720393eca6497253106e4eec75e0Timo Sirainen (ret < 0 && i > TEST_MSG_LEN*2));
afe1da042382720393eca6497253106e4eec75e0Timo Sirainen }
afe1da042382720393eca6497253106e4eec75e0Timo Sirainen message_parser_deinit(&parser, &parts2);
afe1da042382720393eca6497253106e4eec75e0Timo Sirainen test_assert(msg_parts_cmp(parts, parts2));
afe1da042382720393eca6497253106e4eec75e0Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen /* parsing in small blocks from preparsed parts */
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen i_stream_seek(input, 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen test_istream_set_allow_eof(input, FALSE);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen end_of_headers_idx = (strstr(test_msg, "\n-----") - test_msg);
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen parser = message_parser_init_from_parts(parts, input, 0,
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK);
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen for (i = 1; i <= TEST_MSG_LEN*2+1; i++) {
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen test_istream_set_size(input, i/2);
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen if (i > TEST_MSG_LEN*2)
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen test_istream_set_allow_eof(input, TRUE);
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen while ((ret = message_parser_parse_next_block(parser,
eecb235c14b49c01774134ea593c266f2d2c2be1Timo Sirainen &block)) > 0) ;
eecb235c14b49c01774134ea593c266f2d2c2be1Timo Sirainen test_assert((ret == 0 && i/2 <= end_of_headers_idx) ||
7900eb30bac4a46b259522c58362884661483d7cJosef 'Jeff' Sipek (ret < 0 && i/2 > end_of_headers_idx));
7900eb30bac4a46b259522c58362884661483d7cJosef 'Jeff' Sipek }
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen test_assert(message_parser_deinit_from_parts(&parser, &parts2, &error) == 0);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen test_assert(msg_parts_cmp(parts, parts2));
98c217499d578495e982ea6010ebff831e9669aeMartti Rannanjärvi
98c217499d578495e982ea6010ebff831e9669aeMartti Rannanjärvi i_stream_unref(&input);
98c217499d578495e982ea6010ebff831e9669aeMartti Rannanjärvi pool_unref(&pool);
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen test_end();
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen}
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainenstatic void test_message_parser_truncated_mime_headers(void)
f1743785713e7632459d623d5df2108f4b93accbTimo Sirainen{
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstatic const char input_msg[] =
70ead6466f9baa8294e71fc2fba0a4f54f488b5eTimo Sirainen"Content-Type: multipart/mixed; boundary=\":foo\"\n"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen"\n"
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen"--:foo\n"
8d630c15a8ed6f85553467c3a231a273defca5f6Timo Sirainen"--:foo\n"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen"Content-Type: text/plain\n"
ee116df08d0fdab703483e18fe8076b2ef9fd9d7Timo Sirainen"--:foo\n"
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen"Content-Type: text/plain\r\n"
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen"--:foo\n"
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen"Content-Type: text/html\n"
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen"--:foo--\n";
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen struct message_parser_ctx *parser;
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen struct istream *input;
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen struct message_part *parts, *part;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct message_block block;
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen pool_t pool;
c6afd726060aae56b6622c6c52aec10231c4bf1cTimo Sirainen int ret;
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen test_begin("message parser truncated mime headers");
98c217499d578495e982ea6010ebff831e9669aeMartti Rannanjärvi pool = pool_alloconly_create("message parser", 10240);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen input = test_istream_create(input_msg);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen parser = message_parser_init(pool, input, 0, 0);
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen test_assert(ret < 0);
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen message_parser_deinit(&parser, &parts);
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen test_assert((parts->flags & MESSAGE_PART_FLAG_MULTIPART) != 0);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen test_assert(parts->body_size.lines == 8);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen test_assert(parts->body_size.physical_size == 112);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen test_assert(parts->body_size.virtual_size == 112+7);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen test_assert(parts->children->header_size.physical_size == 0);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen test_assert(parts->children->body_size.physical_size == 0);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen test_assert(parts->children->body_size.lines == 0);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen test_assert(parts->children->next->header_size.physical_size == 24);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen test_assert(parts->children->next->header_size.virtual_size == 24);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen test_assert(parts->children->next->header_size.lines == 0);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen test_assert(parts->children->next->next->header_size.physical_size == 24);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen test_assert(parts->children->next->next->header_size.virtual_size == 24);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen test_assert(parts->children->next->next->header_size.lines == 0);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen test_assert(parts->children->next->next->next->header_size.physical_size == 23);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen test_assert(parts->children->next->next->next->header_size.virtual_size == 23);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen test_assert(parts->children->next->next->next->header_size.lines == 0);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen for (part = parts->children; part != NULL; part = part->next) {
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen test_assert(part->body_size.physical_size == 0);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen test_assert(part->body_size.virtual_size == 0);
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen test_assert(parts->children->next->next->next->next == NULL);
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen
cff1f182205e674285cf3ff446a0dcf7afea277dTimo Sirainen i_stream_unref(&input);
cff1f182205e674285cf3ff446a0dcf7afea277dTimo Sirainen pool_unref(&pool);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen test_end();
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen}
e03d986a74128f5ba30fcfda9f6e36578f5d8decTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void test_message_parser_truncated_mime_headers2(void)
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen{
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainenstatic const char input_msg[] =
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen"Content-Type: multipart/mixed; boundary=\"ab\"\n"
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen"\n"
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen"--ab\n"
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen"Content-Type: multipart/mixed; boundary=\"a\"\n"
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen"\n"
d3280fe317a4598c0868cc440e7a1191c06d0db3Timo Sirainen"--ab\n"
d3280fe317a4598c0868cc440e7a1191c06d0db3Timo Sirainen"Content-Type: text/plain\n"
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen"\n"
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen"--a\n\n";
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen struct message_parser_ctx *parser;
6469cf211a57433335641725dc236ebb2b9fdd3bTimo Sirainen struct istream *input;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct message_part *parts;
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen struct message_block block;
6cc4cce2078aca138fbce19305e69e77edcee614Timo Sirainen pool_t pool;
bd6a8056771b6150685dea319ab5a94e021d17f1Josef 'Jeff' Sipek int ret;
9f37ef2a9192e7d47e3d7ac959080fd01120f2e9Aki Tuomi
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen test_begin("message parser truncated mime headers 2");
bd6a8056771b6150685dea319ab5a94e021d17f1Josef 'Jeff' Sipek pool = pool_alloconly_create("message parser", 10240);
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen input = test_istream_create(input_msg);
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen parser = message_parser_init(pool, input, 0, 0);
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen test_assert(ret < 0);
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen message_parser_deinit(&parser, &parts);
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
aa47c9bd1d1fc70cd699c49fd1ca92dbc7615953Timo Sirainen test_assert(parts->header_size.lines == 2);
aa47c9bd1d1fc70cd699c49fd1ca92dbc7615953Timo Sirainen test_assert(parts->header_size.physical_size == 46);
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen test_assert(parts->header_size.virtual_size == 46+2);
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen test_assert(parts->body_size.lines == 8);
aa47c9bd1d1fc70cd699c49fd1ca92dbc7615953Timo Sirainen test_assert(parts->body_size.physical_size == 86);
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen test_assert(parts->body_size.virtual_size == 86+8);
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen test_assert(parts->children->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen test_assert(parts->children->physical_pos == 51);
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen test_assert(parts->children->header_size.lines == 1);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen test_assert(parts->children->header_size.physical_size == 44);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen test_assert(parts->children->header_size.virtual_size == 44+1);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen test_assert(parts->children->body_size.lines == 0);
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen test_assert(parts->children->body_size.physical_size == 0);
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen test_assert(parts->children->children == NULL);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
2584e86cc2d8c31ba30a4109cf4ba09d1e37e28aTimo Sirainen test_assert(parts->children->next->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME));
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen test_assert(parts->children->next->physical_pos == 101);
4b41116563110d00330896a568eff1078c382827Timo Sirainen test_assert(parts->children->next->header_size.lines == 2);
4b41116563110d00330896a568eff1078c382827Timo Sirainen test_assert(parts->children->next->header_size.physical_size == 26);
4b41116563110d00330896a568eff1078c382827Timo Sirainen test_assert(parts->children->next->header_size.virtual_size == 26+2);
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen test_assert(parts->children->next->body_size.lines == 2);
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen test_assert(parts->children->next->body_size.physical_size == 5);
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen test_assert(parts->children->next->body_size.virtual_size == 5+2);
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen test_assert(parts->children->next->children == NULL);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_stream_unref(&input);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen pool_unref(&pool);
c6ce2e251ac75fa650c7fbfa52150eae69386293Martti Rannanjärvi test_end();
c6ce2e251ac75fa650c7fbfa52150eae69386293Martti Rannanjärvi}
b2c1349cf07410aefab0f5b17153af9e5cfcf48fTimo Sirainen
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainenstatic void test_message_parser_truncated_mime_headers3(void)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
dbe64f3893616a4005c8946be75d2dc8f6823d72Timo Sirainenstatic const char input_msg[] =
8a13b020f90e080570658b18c042e7e352c8b14fTimo Sirainen"Content-Type: multipart/mixed; boundary=\"ab\"\n";
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct message_parser_ctx *parser;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct istream *input;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct message_part *parts;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct message_block block;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen pool_t pool;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen int ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen test_begin("message parser truncated mime headers 3");
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen pool = pool_alloconly_create("message parser", 10240);
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen input = test_istream_create(input_msg);
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen parser = message_parser_init(pool, input, 0, 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
f3bb2fbe87425dc89a839908985af496f7f65702Timo Sirainen test_assert(ret < 0);
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen message_parser_deinit(&parser, &parts);
a3ee5ce6ecc8e228ee69300fdd562d7ac8be89a7Timo Sirainen
bd1b2615928a1e8be190cb0405754f0aec8cac2fTimo Sirainen test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen test_assert(parts->header_size.lines == 1);
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen test_assert(parts->header_size.physical_size == 45);
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen test_assert(parts->header_size.virtual_size == 45+1);
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen test_assert(parts->body_size.lines == 0);
a423d985ba7261661475811c22b21b80ec765a71Timo Sirainen test_assert(parts->body_size.physical_size == 0);
2ebeb22b9a8a8bb7fbe2f2e2908478a220792b87Timo Sirainen
a423d985ba7261661475811c22b21b80ec765a71Timo Sirainen test_assert(parts->children == NULL);
bd4d0a1a7c0626452b8d82f37e3ec07267ac9896Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_stream_unref(&input);
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen pool_unref(&pool);
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen test_end();
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen}
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainenstatic void test_message_parser_empty_multipart(void)
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen{
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainenstatic const char input_msg[] =
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen"Content-Type: multipart/mixed; boundary=\"ab\"\n"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen"\n"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen"body\n";
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct message_parser_ctx *parser;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct istream *input;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct message_part *parts;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct message_block block;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen pool_t pool;
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen int ret;
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen test_begin("message parser truncated mime headers 3");
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen pool = pool_alloconly_create("message parser", 10240);
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen input = test_istream_create(input_msg);
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen
2c70086138fe7ac9abf52cd4223c224fe0bbb488Timo Sirainen parser = message_parser_init(pool, input, 0, 0);
2c70086138fe7ac9abf52cd4223c224fe0bbb488Timo Sirainen while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
2c70086138fe7ac9abf52cd4223c224fe0bbb488Timo Sirainen test_assert(ret < 0);
2c70086138fe7ac9abf52cd4223c224fe0bbb488Timo Sirainen message_parser_deinit(&parser, &parts);
2c70086138fe7ac9abf52cd4223c224fe0bbb488Timo Sirainen
2c70086138fe7ac9abf52cd4223c224fe0bbb488Timo Sirainen test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainen test_assert(parts->header_size.lines == 2);
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainen test_assert(parts->header_size.physical_size == 46);
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainen test_assert(parts->header_size.virtual_size == 46+2);
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainen test_assert(parts->body_size.lines == 1);
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen test_assert(parts->body_size.physical_size == 5);
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen test_assert(parts->body_size.virtual_size == 5+1);
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen test_assert(parts->children == NULL);
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen i_stream_unref(&input);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen pool_unref(&pool);
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen test_end();
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstatic void test_message_parser_duplicate_mime_boundary(void)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainenstatic const char input_msg[] =
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen"Content-Type: multipart/mixed; boundary=\"a\"\n"
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen"\n"
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen"--a\n"
d938e9e4ec4c0f326dffd5ebe42c1ad893ce7e52Timo Sirainen"Content-Type: multipart/mixed; boundary=\"a\"\n"
eecb235c14b49c01774134ea593c266f2d2c2be1Timo Sirainen"\n"
eecb235c14b49c01774134ea593c266f2d2c2be1Timo Sirainen"--a\n"
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen"Content-Type: text/plain\n"
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen"\n"
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen"body\n";
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen struct message_parser_ctx *parser;
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen struct istream *input;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen struct message_part *parts;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen struct message_block block;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen pool_t pool;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen int ret;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen test_begin("message parser duplicate mime boundary");
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen pool = pool_alloconly_create("message parser", 10240);
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen input = test_istream_create(input_msg);
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen parser = message_parser_init(pool, input, 0, 0);
546335814920fb6b5b44c68c7803e654eefeae9dTimo Sirainen while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
546335814920fb6b5b44c68c7803e654eefeae9dTimo Sirainen test_assert(ret < 0);
546335814920fb6b5b44c68c7803e654eefeae9dTimo Sirainen message_parser_deinit(&parser, &parts);
4b41218f9e09386ad5d8f279355aad1dfb64392dTimo Sirainen
4b41218f9e09386ad5d8f279355aad1dfb64392dTimo Sirainen test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen test_assert(parts->header_size.lines == 2);
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen test_assert(parts->header_size.physical_size == 45);
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen test_assert(parts->header_size.virtual_size == 45+2);
eb1572d7c44ebc7b0b039d085c3dbab2ef7043ddTimo Sirainen test_assert(parts->body_size.lines == 7);
eb1572d7c44ebc7b0b039d085c3dbab2ef7043ddTimo Sirainen test_assert(parts->body_size.physical_size == 84);
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen test_assert(parts->body_size.virtual_size == 84+7);
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen test_assert(parts->children->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen test_assert(parts->children->physical_pos == 49);
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen test_assert(parts->children->header_size.lines == 2);
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen test_assert(parts->children->header_size.physical_size == 45);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen test_assert(parts->children->header_size.virtual_size == 45+2);
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen test_assert(parts->children->body_size.lines == 4);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen test_assert(parts->children->body_size.physical_size == 35);
42507d758b053bb483de58fba55c73a9eb5d3fbaTimo Sirainen test_assert(parts->children->body_size.virtual_size == 35+4);
c0c346d0e6a76137ba5006857ed03b1227804170Timo Sirainen test_assert(parts->children->children->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME));
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen test_assert(parts->children->children->physical_pos == 98);
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen test_assert(parts->children->children->header_size.lines == 2);
382f23541ce657be87b079abd6784d376fb4eb43Timo Sirainen test_assert(parts->children->children->header_size.physical_size == 26);
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainen test_assert(parts->children->children->header_size.virtual_size == 26+2);
97a5e150cacf7da9dd200e317b75460352038d65Timo Sirainen test_assert(parts->children->children->body_size.lines == 1);
3743948b65bd079cd6f2502d35bd21666c1a2f5aAki Tuomi test_assert(parts->children->children->body_size.physical_size == 5);
134987bc3b685d7ec71c04e9337f7125cff0698fTimo Sirainen test_assert(parts->children->children->body_size.virtual_size == 5+1);
42507d758b053bb483de58fba55c73a9eb5d3fbaTimo Sirainen
817d027593510c3ba70ad542ce0011f5f6916d1eTimo Sirainen i_stream_unref(&input);
817d027593510c3ba70ad542ce0011f5f6916d1eTimo Sirainen pool_unref(&pool);
817d027593510c3ba70ad542ce0011f5f6916d1eTimo Sirainen test_end();
817d027593510c3ba70ad542ce0011f5f6916d1eTimo Sirainen}
817d027593510c3ba70ad542ce0011f5f6916d1eTimo Sirainen
6ae329de09afb7214c906d762320847e05469d53Timo Sirainenstatic void test_message_parser_garbage_suffix_mime_boundary(void)
6ae329de09afb7214c906d762320847e05469d53Timo Sirainen{
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainenstatic const char input_msg[] =
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen"Content-Type: multipart/mixed; boundary=\"a\"\n"
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen"\n"
7e2671b295927b461adc8b6c4ed6a1c4761fb323Timo Sirainen"--ab\n"
7e2671b295927b461adc8b6c4ed6a1c4761fb323Timo Sirainen"Content-Type: multipart/mixed; boundary=\"a\"\n"
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen"\n"
fcfe85637e1ee14a9fc39c41fd6ceca106301542Timo Sirainen"--ac\n"
fcfe85637e1ee14a9fc39c41fd6ceca106301542Timo Sirainen"Content-Type: text/plain\n"
fcfe85637e1ee14a9fc39c41fd6ceca106301542Timo Sirainen"\n"
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen"body\n";
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen struct message_parser_ctx *parser;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen struct istream *input;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct message_part *parts;
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen struct message_block block;
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen pool_t pool;
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen int ret;
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen test_begin("message parser garbage suffix mime boundary");
4bbd396aa6198c84f3f7763b6e8a63a26e97e141Timo Sirainen pool = pool_alloconly_create("message parser", 10240);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen input = test_istream_create(input_msg);
7baab0b0b60df7ce9093d0881cd322dff1e79491Timo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen parser = message_parser_init(pool, input, 0, 0);
3f91e60401495a4046c73992fabaa5e77200a451Timo Sirainen while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen test_assert(ret < 0);
3857e2945a3b6744d603f0f5a656849ed8436ba3Timo Sirainen message_parser_deinit(&parser, &parts);
3857e2945a3b6744d603f0f5a656849ed8436ba3Timo Sirainen
f90cbe597c41d5cc91debd371f8648bd8e6ffbc2Timo Sirainen test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen test_assert(parts->header_size.lines == 2);
33b469d1ca66dd2cc496d2d990b8b98e72952a29Timo Sirainen test_assert(parts->header_size.physical_size == 45);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen test_assert(parts->header_size.virtual_size == 45+2);
58ba0fe5a6904d3a65cfe268411f4cbb881234eeTimo Sirainen test_assert(parts->body_size.lines == 7);
58ba0fe5a6904d3a65cfe268411f4cbb881234eeTimo Sirainen test_assert(parts->body_size.physical_size == 86);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen test_assert(parts->body_size.virtual_size == 86+7);
6b0d8106ae51ffc6ce45636b34d2e21cbefca7fdTimo Sirainen test_assert(parts->children->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen test_assert(parts->children->physical_pos == 50);
eb64c3586d854cddd693f0b811d897399076a441Timo Sirainen test_assert(parts->children->header_size.lines == 2);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen test_assert(parts->children->header_size.physical_size == 45);
eb64c3586d854cddd693f0b811d897399076a441Timo Sirainen test_assert(parts->children->header_size.virtual_size == 45+2);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen test_assert(parts->children->body_size.lines == 4);
7f735cb86b2d8abd8f230089065eacfc24e9e5d6Timo Sirainen test_assert(parts->children->body_size.physical_size == 36);
7f735cb86b2d8abd8f230089065eacfc24e9e5d6Timo Sirainen test_assert(parts->children->body_size.virtual_size == 36+4);
7f735cb86b2d8abd8f230089065eacfc24e9e5d6Timo Sirainen test_assert(parts->children->children->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME));
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen test_assert(parts->children->children->physical_pos == 100);
b3484b5b1f47e4cf112f0e371478a2d7794b31bbTimo Sirainen test_assert(parts->children->children->header_size.lines == 2);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen test_assert(parts->children->children->header_size.physical_size == 26);
d81131d3bbb4f0befb62a661d1785cf8c84a17e2Timo Sirainen test_assert(parts->children->children->header_size.virtual_size == 26+2);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen test_assert(parts->children->children->body_size.lines == 1);
9456a4a3e74929f9d3d5b00b93be6d8eb69bc52aTimo Sirainen test_assert(parts->children->children->body_size.physical_size == 5);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen test_assert(parts->children->children->body_size.virtual_size == 5+1);
4e3bcf7fdaeef92dd07a2acb1ded58422a907e87Timo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen i_stream_unref(&input);
19e161dd9e2c3a2ffc96ee8852bec0720cb30d1cTimo Sirainen pool_unref(&pool);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen test_end();
540555c5b435203e1c26c8e7b924b2643ae07ae3Timo Sirainen}
540555c5b435203e1c26c8e7b924b2643ae07ae3Timo Sirainen
540555c5b435203e1c26c8e7b924b2643ae07ae3Timo Sirainenstatic void test_message_parser_continuing_mime_boundary(void)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstatic const char input_msg[] =
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen"Content-Type: multipart/mixed; boundary=\"a\"\n"
0d86aa0d47f7393c669c084b34c0537b193688adTimo Sirainen"\n"
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen"--a\n"
7631f16156aca373004953fe6b01a7f343fb47e0Timo Sirainen"Content-Type: multipart/mixed; boundary=\"ab\"\n"
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen"\n"
aa247243412a49f9bdebf7255e131dc6ece4ed46Timo Sirainen"--ab\n"
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen"Content-Type: text/plain\n"
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen"\n"
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen"body\n";
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen struct message_parser_ctx *parser;
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen struct istream *input;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct message_part *parts;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct message_block block;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen pool_t pool;
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen int ret;
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen test_begin("message parser continuing mime boundary");
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen pool = pool_alloconly_create("message parser", 10240);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen input = test_istream_create(input_msg);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
c0225f7f6b43d34dc58c17d3304f0fd60ab89894Timo Sirainen parser = message_parser_init(pool, input, 0, 0);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen test_assert(ret < 0);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen message_parser_deinit(&parser, &parts);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen test_assert(parts->header_size.lines == 2);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen test_assert(parts->header_size.physical_size == 45);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen test_assert(parts->header_size.virtual_size == 45+2);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen test_assert(parts->body_size.lines == 7);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen test_assert(parts->body_size.physical_size == 86);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen test_assert(parts->body_size.virtual_size == 86+7);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen test_assert(parts->children->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen test_assert(parts->children->physical_pos == 49);
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen test_assert(parts->children->header_size.lines == 2);
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen test_assert(parts->children->header_size.physical_size == 46);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen test_assert(parts->children->header_size.virtual_size == 46+2);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen test_assert(parts->children->body_size.lines == 4);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen test_assert(parts->children->body_size.physical_size == 36);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen test_assert(parts->children->body_size.virtual_size == 36+4);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen test_assert(parts->children->children->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME));
e53ab6c7081246c865917f9aa0eff031a08ad1e7Timo Sirainen test_assert(parts->children->children->physical_pos == 100);
e53ab6c7081246c865917f9aa0eff031a08ad1e7Timo Sirainen test_assert(parts->children->children->header_size.lines == 2);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen test_assert(parts->children->children->header_size.physical_size == 26);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen test_assert(parts->children->children->header_size.virtual_size == 26+2);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen test_assert(parts->children->children->body_size.lines == 1);
21aaa6affb9f134112b75b5db737309fc35ef1cfMartti Rannanjärvi test_assert(parts->children->children->body_size.physical_size == 5);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen test_assert(parts->children->children->body_size.virtual_size == 5+1);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen i_stream_unref(&input);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen pool_unref(&pool);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen test_end();
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen}
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainenstatic void test_message_parser_no_eoh(void)
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen{
838e367716bbd5e44b4a1691db9cbf72af53e9f0Timo Sirainen static const char input_msg[] = "a:b\n";
0206dc57f2c04da69599dea5816235cfeb2b897aMartti Rannanjärvi struct message_parser_ctx *parser;
0206dc57f2c04da69599dea5816235cfeb2b897aMartti Rannanjärvi struct istream *input;
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen struct message_part *parts;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct message_block block;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen pool_t pool;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen test_begin("message parser no EOH");
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen pool = pool_alloconly_create("message parser", 10240);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen input = test_istream_create(input_msg);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen parser = message_parser_init(pool, input, 0, 0);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen test_assert(message_parser_parse_next_block(parser, &block) > 0 &&
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen block.hdr != NULL && strcmp(block.hdr->name, "a") == 0 &&
13e130c3af3032982de6b1d13c6dcddda9164848Timo Sirainen block.hdr->value_len == 1 && block.hdr->value[0] == 'b');
13e130c3af3032982de6b1d13c6dcddda9164848Timo Sirainen test_assert(message_parser_parse_next_block(parser, &block) > 0 &&
13e130c3af3032982de6b1d13c6dcddda9164848Timo Sirainen block.hdr == NULL && block.size == 0);
13e130c3af3032982de6b1d13c6dcddda9164848Timo Sirainen test_assert(message_parser_parse_next_block(parser, &block) < 0);
13e130c3af3032982de6b1d13c6dcddda9164848Timo Sirainen message_parser_deinit(&parser, &parts);
13e130c3af3032982de6b1d13c6dcddda9164848Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen i_stream_unref(&input);
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen pool_unref(&pool);
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen test_end();
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen}
310767ca33e7636d40ec45dee68a2c319a5fa3c0Timo Sirainen
310767ca33e7636d40ec45dee68a2c319a5fa3c0Timo Sirainenint main(void)
310767ca33e7636d40ec45dee68a2c319a5fa3c0Timo Sirainen{
5f44975ec6c5755dd74bcd4c47a123a7242ecab3Timo Sirainen static void (*test_functions[])(void) = {
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen test_message_parser_small_blocks,
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen test_message_parser_truncated_mime_headers,
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen test_message_parser_truncated_mime_headers2,
6c51e3c3dc8dc5dc6fef2280b7c2c9ebef3de8f0Aki Tuomi test_message_parser_truncated_mime_headers3,
6c51e3c3dc8dc5dc6fef2280b7c2c9ebef3de8f0Aki Tuomi test_message_parser_empty_multipart,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen test_message_parser_duplicate_mime_boundary,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen test_message_parser_garbage_suffix_mime_boundary,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen test_message_parser_continuing_mime_boundary,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen test_message_parser_no_eoh,
e4c90f0b88e40a8f92b8f5e1f1a3ea701e5c965cTimo Sirainen NULL
defb12ecd360df672ffb2f4dbf4d1218a0a9549cTimo Sirainen };
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return test_run(test_functions);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen