1 /* Copyright (c) 2020 Dovecot authors, see the included COPYING file */
2
3 #include "lib.h"
4 #include "istream.h"
5 #include "message-size.h"
6 #include "test-common.h"
7
8 static const char test_msg[] =
9 "Return-Path: <test@example.org>\n"
10 "Subject: Hello world\n"
11 "From: Test User <test@example.org>\n"
12 "To: Another User <test2@example.org>\n"
13 "Message-Id: <1.2.3.4@example>\n"
14 "Mime-Version: 1.0\n"
15 "Date: Sun, 23 May 2007 04:58:08 +0300\n"
16 "Content-Type: multipart/signed; micalg=pgp-sha1;\n"
17 " protocol=\"application/pgp-signature\";\n"
18 " boundary=\"=-GNQXLhuj24Pl1aCkk4/d\"\n"
19 "\n"
20 "--=-GNQXLhuj24Pl1aCkk4/d\n"
21 "Content-Type: text/plain\n"
22 "Content-Transfer-Encoding: quoted-printable\n"
23 "\n"
24 "There was a day=20\n"
25 "a happy=20day\n"
26 "\n"
27 "--=-GNQXLhuj24Pl1aCkk4/d\n"
28 "Content-Type: application/pgp-signature; name=signature.asc\n"
29 "\n"
30 "-----BEGIN PGP SIGNATURE-----\n"
31 "Version: GnuPG v1.2.4 (GNU/Linux)\n"
32 "\n"
33 "invalid\n"
34 "-----END PGP SIGNATURE-----\n"
35 "\n"
36 "--=-GNQXLhuj24Pl1aCkk4/d--\n"
37 "\n"
38 "\n";
39
40 static const char test_msg_with_nuls[] =
41 "Return-Path: <test@example.org>\n"
42 "Subject: Hello world\n"
43 "From: Test User <test@example.org>\n"
44 "To: Another User <test2@example.org>\n"
45 "Message-Id: <1.2.3.4@example>\n"
46 "Mime-Version: 1.0\0\n"
47 "Date: Sun, 23 May 2007 04:58:08 +0300\n"
48 "Content-Type: multipart/signed; micalg=pgp-sha1;\n"
49 " protocol=\"application/pgp-signature\";\n"
50 " boundary=\"=-GNQXLhuj24Pl1aCkk4/d\"\n"
51 "\n"
52 "--=-GNQXLhuj24Pl1aCkk4/d\n"
53 "\n"
54 "Content-Type: text/plain\n"
55 "Content-Transfer-Encoding: quoted-printable\n"
56 "\n"
57 "There was\0 a day=20\n"
58 "a happy=20day\n"
59 "\n"
60 "--=-GNQXLhuj24Pl1aCkk4/d\n"
61 "Content-Type: application/pgp-signature; name=signature.asc\n"
62 "\n"
63 "-----BEGIN PGP SIGNATURE-----\n"
64 "Version: GnuPG v1.2.4 (GNU/Linux)\n"
65 "\n"
66 "inva\0lid\n"
67 "-----END PGP SIGNATURE-----\n"
68 "\n"
69 "--=-GNQXLhuj24Pl1aCkk4/d--\n"
70 "\n"
71 "\n";
72
73 struct test_case {
74 const char *test_name;
75 const char *message;
76 bool has_nuls;
77 unsigned int body_newlines;
78 unsigned int header_newlines;
79 unsigned int message_len;
80 unsigned int header_len;
81 };
82 static const struct test_case test_cases[] = {
83 {
84 .test_name = "message size",
85 .message = test_msg,
86 .has_nuls = FALSE,
87 .body_newlines = 19,
88 .header_newlines = 11,
89 .message_len = sizeof(test_msg)-1,
90 .header_len = 335,
91 },
92 {
93 .test_name = "message size with nuls",
94 .message = test_msg_with_nuls,
95 .has_nuls = TRUE,
96 .body_newlines = 20,
97 .header_newlines = 11,
98 .message_len = sizeof(test_msg_with_nuls)-1,
99 .header_len = 336,
100 },
101 };
102
test_message_size(void)103 static void test_message_size(void)
104 {
105 struct istream *input;
106 struct message_size body_size, header_size;
107 bool has_nuls;
108 bool last_cr;
109 unsigned int i;
110
111 for (i = 0; i < N_ELEMENTS(test_cases); i++) {
112 test_begin(test_cases[i].test_name);
113 input = i_stream_create_from_data(test_cases[i].message,
114 test_cases[i].message_len);
115
116 /* Read physical_size */
117 message_get_header_size(input, &header_size, &has_nuls);
118 test_assert_idx(has_nuls == test_cases[i].has_nuls, i);
119 test_assert_idx(input->v_offset == test_cases[i].header_len, i);
120 message_get_body_size(input, &body_size, &has_nuls);
121 test_assert_idx(has_nuls == test_cases[i].has_nuls, i);
122 test_assert_idx(input->v_offset - body_size.physical_size ==
123 test_cases[i].header_len, i);
124 test_assert_idx(body_size.physical_size + header_size.physical_size ==
125 test_cases[i].message_len, i);
126
127 /* Test last_cr handling */
128 i_stream_seek(input, 0);
129 message_skip_virtual(input, 0, &last_cr);
130 test_assert_idx(!last_cr, i);
131 message_skip_virtual(input, header_size.virtual_size-1, &last_cr);
132 test_assert_idx(last_cr, i);
133 message_skip_virtual(input, 2, &last_cr);
134 test_assert_idx(!last_cr, i);
135
136 /* Skipped header size so read body again */
137 message_get_body_size(input, &body_size, &has_nuls);
138 test_assert_idx(has_nuls == test_cases[i].has_nuls, i);
139 test_assert_idx(input->v_offset - body_size.physical_size ==
140 test_cases[i].header_len, i);
141 test_assert_idx(body_size.physical_size + test_cases[i].body_newlines ==
142 body_size.virtual_size, i);
143 test_assert_idx(body_size.virtual_size + header_size.virtual_size -
144 test_cases[i].body_newlines - test_cases[i].header_newlines ==
145 test_cases[i].message_len, i);
146
147 i_stream_unref(&input);
148 test_end();
149 }
150 }
151
main(void)152 int main(void)
153 {
154 static void (*const test_functions[])(void) = {
155 test_message_size,
156 NULL
157 };
158 return test_run(test_functions);
159 }
160