1 /* Copyright (c) 2020 Dovecot authors, see the included COPYING file */
2
3 #include "lib.h"
4 #include "str.h"
5 #include "str-sanitize.h"
6 #include "test-common.h"
7 #include "smtp-syntax.h"
8
9 /*
10 * Valid string parse tests
11 */
12
13 struct valid_string_parse_test {
14 const char *input, *parsed, *output;
15 };
16
17 static const struct valid_string_parse_test
18 valid_string_parse_tests[] = {
19 {
20 .input = "",
21 .parsed = "",
22 },
23 {
24 .input = "atom",
25 .parsed = "atom",
26 },
27 {
28 .input = "abcdefghijklmnopqrstuvwxyz"
29 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
30 "0123456789!#$%&'*+-/=?^_`{|}~",
31 .parsed = "abcdefghijklmnopqrstuvwxyz"
32 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
33 "0123456789!#$%&'*+-/=?^_`{|}~",
34 },
35 {
36 .input = "\"quoted-string\"",
37 .parsed = "quoted-string",
38 .output = "quoted-string",
39 },
40 {
41 .input = "\"quoted \\\"string\\\"\"",
42 .parsed = "quoted \"string\"",
43 },
44 {
45 .input = "\"quoted \\\\string\\\\\"",
46 .parsed = "quoted \\string\\",
47 },
48 };
49
50 static const unsigned int valid_string_parse_test_count =
51 N_ELEMENTS(valid_string_parse_tests);
52
test_smtp_string_parse_valid(void)53 static void test_smtp_string_parse_valid(void)
54 {
55 unsigned int i;
56
57 for (i = 0; i < valid_string_parse_test_count; i++) T_BEGIN {
58 const struct valid_string_parse_test *test =
59 &valid_string_parse_tests[i];
60 const char *parsed, *error = NULL;
61 int ret;
62
63 ret = smtp_string_parse(test->input, &parsed, &error);
64
65 test_begin(t_strdup_printf("smtp string valid [%d]", i));
66 test_out_reason(t_strdup_printf("parse(\"%s\")", test->input),
67 ret >= 0, error);
68 test_assert(ret != 0 || *test->input == '\0');
69
70 if (!test_has_failed()) {
71 string_t *encoded;
72 const char *output;
73
74 test_out(t_strdup_printf("parsed = \"%s\"", parsed),
75 null_strcmp(parsed, test->parsed) == 0);
76
77 encoded = t_str_new(255);
78 smtp_string_write(encoded, parsed);
79 output = (test->output == NULL ?
80 test->input : test->output);
81 test_out(t_strdup_printf("write() = \"%s\"",
82 str_c(encoded)),
83 strcmp(str_c(encoded), output) == 0);
84 }
85 test_end();
86 } T_END;
87 }
88
89 /*
90 * Invalid string parse tests
91 */
92
93 struct invalid_string_parse_test {
94 const char *input;
95 };
96
97 static const struct invalid_string_parse_test
98 invalid_string_parse_tests[] = {
99 {
100 .input = " ",
101 },
102 {
103 .input = "\\",
104 },
105 {
106 .input = "\"",
107 },
108 {
109 .input = "\"aa",
110 },
111 {
112 .input = "aa\"",
113 },
114 };
115
116 static const unsigned int invalid_string_parse_test_count =
117 N_ELEMENTS(invalid_string_parse_tests);
118
test_smtp_string_parse_invalid(void)119 static void test_smtp_string_parse_invalid(void)
120 {
121 unsigned int i;
122
123 for (i = 0; i < invalid_string_parse_test_count; i++) T_BEGIN {
124 const struct invalid_string_parse_test *test =
125 &invalid_string_parse_tests[i];
126 const char *parsed, *error;
127 int ret;
128
129 ret = smtp_string_parse(test->input, &parsed, &error);
130
131 test_begin(t_strdup_printf("smtp string invalid [%d]", i));
132 test_out_reason(t_strdup_printf("parse(\"%s\")", test->input),
133 ret < 0, error);
134 test_end();
135 } T_END;
136 }
137
138 /*
139 * Tests
140 */
141
main(void)142 int main(void)
143 {
144 static void (*test_functions[])(void) = {
145 test_smtp_string_parse_valid,
146 test_smtp_string_parse_invalid,
147 NULL
148 };
149 return test_run(test_functions);
150 }
151