1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
/* Copyright (c) 2014-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "istream.h"
#include "message-parser.h"
#include "test-common.h"
static const char test_msg[] =
"From user@domain Fri Feb 22 17:06:23 2008\n"
"From: user@domain.org\n"
"Date: Sat, 24 Mar 2007 23:00:00 +0200\n"
"Mime-Version: 1.0\n"
"Content-Type: multipart/mixed; boundary=\"foo bar\"\n"
"\n"
"Root MIME prologue\n"
"\n"
"--foo bar\n"
"Content-Type: text/x-myown; charset=us-ascii\n"
"\n"
"hello\n"
"\n"
"--foo bar\n"
"Content-Type: message/rfc822\n"
"\n"
"From: sub@domain.org\n"
"Date: Sun, 12 Aug 2012 12:34:56 +0300\n"
"Subject: submsg\n"
"Content-Type: multipart/alternative; boundary=\"sub1\"\n"
"\n"
"Sub MIME prologue\n"
"--sub1\n"
"Content-Type: text/html\n"
"\n"
"<p>Hello world</p>\n"
"\n"
"--sub1\n"
"Content-Type: multipart/alternative; boundary=\"sub2\"\n"
"\n"
"--sub2\n"
"Content-Type: multipart/alternative; boundary=\"sub3\"\n"
"\n"
"--sub3\n"
"\n"
"sub3 text\n"
"--sub3\n"
"\n"
"sub3 text2\n"
"--sub3--\n"
"\n"
"sub2 text\n"
"--sub2\n"
"\n"
"sub2 text2\n"
"--sub1--\n"
"Sub MIME epilogue\n"
"\n"
"--foo bar\n"
"Content-Type: text/plain\n"
"\n"
"Another part\n"
"--foo bar--\n"
"Root MIME epilogue\n"
"\n";
#define TEST_MSG_LEN (sizeof(test_msg)-1)
static void test_message_part_idx(void)
{
const struct message_parser_settings set = { .flags = 0 };
struct message_parser_ctx *parser;
struct istream *input;
struct message_part *parts, *part, *prev_part;
struct message_block block;
unsigned int i, prev_idx = 0, part_idx;
pool_t pool;
int ret;
test_begin("message part indexes");
pool = pool_alloconly_create("message parser", 10240);
input = i_stream_create_from_data(test_msg, TEST_MSG_LEN);
parser = message_parser_init(pool, input, &set);
while ((ret = message_parser_parse_next_block(parser, &block)) > 0) {
part_idx = message_part_to_idx(block.part);
test_assert(part_idx >= prev_idx);
prev_idx = part_idx;
}
test_assert(ret < 0);
message_parser_deinit(&parser, &parts);
test_assert(input->stream_errno == 0);
part = message_part_by_idx(parts, 0);
test_assert(part == parts);
test_assert(message_part_by_idx(parts, 1) == parts->children);
for (i = 1; i < 11; i++) {
prev_part = part;
part = message_part_by_idx(parts, i);
test_assert(part != NULL);
test_assert(part != NULL && message_part_to_idx(part) == i);
test_assert(part != NULL && prev_part != NULL &&
prev_part->physical_pos < part->physical_pos);
}
test_assert(message_part_by_idx(parts, i) == NULL);
i_stream_unref(&input);
pool_unref(&pool);
test_end();
}
int main(void)
{
static void (*const test_functions[])(void) = {
test_message_part_idx,
NULL
};
return test_run(test_functions);
}
|