1 /* Copyright (c) 2009-2018 Dovecot authors, see the included COPYING file */
2
3 #include "test-lib.h"
4 #include "array.h"
5
test_p_strdup(void)6 static void test_p_strdup(void)
7 {
8 test_begin("p_strdup()");
9 test_assert(p_strdup(default_pool, NULL) == NULL);
10
11 const char *src = "foo";
12 char *str = p_strdup(default_pool, src);
13 test_assert(str != src && str != NULL && strcmp(src, str) == 0);
14 p_free(default_pool, str);
15
16 test_end();
17 }
18
test_p_strndup(void)19 static void test_p_strndup(void)
20 {
21 struct {
22 const char *input;
23 const char *output;
24 size_t len;
25 } tests[] = {
26 { "foo", "fo", 2 },
27 { "foo", "foo", 3 },
28 { "foo", "foo", 4 },
29 { "foo\0more", "foo", 8 },
30 };
31 test_begin("p_strndup()");
32
33 for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) {
34 char *str = p_strndup(default_pool, tests[i].input,
35 tests[i].len);
36 test_assert_strcmp_idx(str, tests[i].output, i);
37 p_free(default_pool, str);
38 }
39 test_end();
40 }
41
test_p_strdup_empty(void)42 static void test_p_strdup_empty(void)
43 {
44 test_begin("p_strdup_empty()");
45 test_assert(p_strdup_empty(default_pool, NULL) == NULL);
46 test_assert(p_strdup_empty(default_pool, "") == NULL);
47
48 const char *src = "foo";
49 char *str = p_strdup_empty(default_pool, src);
50 test_assert(str != src && str != NULL && strcmp(src, str) == 0);
51 p_free(default_pool, str);
52
53 test_end();
54 }
55
test_p_strdup_until(void)56 static void test_p_strdup_until(void)
57 {
58 const char src[] = "foo\0bar";
59 char *str;
60
61 test_begin("p_strdup_until()");
62 str = p_strdup_until(default_pool, src, src+2);
63 test_assert(strcmp(str, "fo") == 0);
64 p_free(default_pool, str);
65
66 str = p_strdup_until(default_pool, src, src+3);
67 test_assert(strcmp(str, "foo") == 0);
68 p_free(default_pool, str);
69
70 /* \0 is ignored */
71 str = p_strdup_until(default_pool, src, src+7);
72 test_assert(memcmp(str, src, sizeof(src)) == 0);
73 p_free(default_pool, str);
74
75 str = p_strdup_until(default_pool, src, src+8);
76 test_assert(memcmp(str, src, sizeof(src)) == 0);
77 p_free(default_pool, str);
78
79 test_end();
80 }
81
test_p_strarray_dup(void)82 static void test_p_strarray_dup(void)
83 {
84 const char *input[][3] = {
85 { NULL },
86 { "a", NULL },
87 { "foobar", NULL },
88 { "a", "foo", NULL }
89 };
90 const char **ret;
91 unsigned int i, j;
92
93 test_begin("p_strarray_dup");
94
95 for (i = 0; i < N_ELEMENTS(input); i++) {
96 ret = p_strarray_dup(default_pool, input[i]);
97 for (j = 0; input[i][j] != NULL; j++) {
98 test_assert(strcmp(input[i][j], ret[j]) == 0);
99 test_assert(input[i][j] != ret[j]);
100 }
101 test_assert(ret[j] == NULL);
102 i_free(ret);
103 }
104 test_end();
105 }
106
test_t_strsplit(void)107 static void test_t_strsplit(void)
108 {
109 struct {
110 const char *input;
111 const char *const *output;
112 } tests[] = {
113 /* empty string -> empty array. was this perhaps a mistake for
114 the API to do this originally?.. can't really change now
115 anyway. */
116 { "", (const char *const []) { NULL } },
117 { "\n", (const char *const []) { "", "", NULL } },
118 { "\n\n", (const char *const []) { "", "", "", NULL } },
119 { "foo", (const char *const []) { "foo", NULL } },
120 { "foo\n", (const char *const []) { "foo", "", NULL } },
121 { "foo\nbar", (const char *const []) { "foo", "bar", NULL } },
122 { "foo\nbar\n", (const char *const []) { "foo", "bar", "", NULL } },
123 { "\nfoo\n\nbar\n\n", (const char *const []) { "", "foo", "", "bar", "", "", NULL } },
124 };
125 const char *const *args, *const *args2, *const *args3;
126
127 test_begin("t_strsplit");
128
129 for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) {
130 /* split_str_fast() with single separator */
131 args = t_strsplit(tests[i].input, "\n");
132 /* split_str_slow() with a secondary separator */
133 args2 = t_strsplit(tests[i].input, "\r\n");
134 /* also as suffix */
135 args3 = t_strsplit(tests[i].input, "\n\r");
136 for (unsigned int j = 0; tests[i].output[j] != NULL; j++) {
137 test_assert_idx(null_strcmp(tests[i].output[j], args[j]) == 0, i);
138 test_assert_idx(null_strcmp(args[j], args2[j]) == 0, i);
139 test_assert_idx(null_strcmp(args[j], args3[j]) == 0, i);
140 }
141 }
142 test_end();
143 }
144
test_t_strsplit_spaces(void)145 static void test_t_strsplit_spaces(void)
146 {
147 struct {
148 const char *input;
149 const char *const *output;
150 } tests[] = {
151 /* empty strings */
152 { "", (const char *const []) { NULL } },
153 { "\n", (const char *const []) { NULL } },
154 { "\n\n", (const char *const []) { NULL } },
155 /* normal */
156 { "foo", (const char *const []) { "foo", NULL } },
157 { "foo\n", (const char *const []) { "foo", NULL } },
158 { "foo\nbar", (const char *const []) { "foo", "bar", NULL } },
159 { "foo\nbar\n", (const char *const []) { "foo", "bar", NULL } },
160 { "\nfoo\n\nbar\n\n", (const char *const []) { "foo", "bar", NULL } },
161 };
162 const char *const *args, *const *args2, *const *args3;
163
164 test_begin("t_strsplit_spaces");
165
166 for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) {
167 args = t_strsplit_spaces(tests[i].input, "\n");
168 /* test also with a secondary nonexistent separator */
169 args2 = t_strsplit_spaces(tests[i].input, "\r\n");
170 /* also as suffix */
171 args3 = t_strsplit_spaces(tests[i].input, "\n\r");
172 for (unsigned int j = 0; tests[i].output[j] != NULL; j++) {
173 test_assert_idx(null_strcmp(tests[i].output[j], args[j]) == 0, i);
174 test_assert_idx(null_strcmp(args[j], args2[j]) == 0, i);
175 test_assert_idx(null_strcmp(args[j], args3[j]) == 0, i);
176 }
177 }
178
179 /* multiple separators */
180 args = t_strsplit_spaces(" , , ,str1 , ,,, , str2 , ", " ,");
181 test_assert(strcmp(args[0], "str1") == 0);
182 test_assert(strcmp(args[1], "str2") == 0);
183 test_assert(args[2] == NULL);
184 test_end();
185 }
186
test_t_str_replace(void)187 static void test_t_str_replace(void)
188 {
189 test_begin("t_str_replace");
190 test_assert(strcmp(t_str_replace("foo", 'a', 'b'), "foo") == 0);
191 test_assert(strcmp(t_str_replace("fooa", 'a', 'b'), "foob") == 0);
192 test_assert(strcmp(t_str_replace("afooa", 'a', 'b'), "bfoob") == 0);
193 test_assert(strcmp(t_str_replace("", 'a', 'b'), "") == 0);
194 test_assert(strcmp(t_str_replace("a", 'a', 'b'), "b") == 0);
195 test_assert(strcmp(t_str_replace("aaa", 'a', 'b'), "bbb") == 0);
196 test_assert(strcmp(t_str_replace("bbb", 'a', 'b'), "bbb") == 0);
197 test_assert(strcmp(t_str_replace("aba", 'a', 'b'), "bbb") == 0);
198 test_end();
199 }
200
test_t_str_oneline(void)201 static void test_t_str_oneline(void)
202 {
203 test_begin("t_str_oneline");
204 test_assert(strcmp(t_str_oneline("\n"), "") == 0);
205 test_assert(strcmp(t_str_oneline("\r"), "") == 0);
206 test_assert(strcmp(t_str_oneline("\n\n"), "") == 0);
207 test_assert(strcmp(t_str_oneline("\r\r"), "") == 0);
208 test_assert(strcmp(t_str_oneline("\r\n"), "") == 0);
209 test_assert(strcmp(t_str_oneline("\r\n\r\n"), "") == 0);
210 test_assert(strcmp(t_str_oneline("\n\r"), "") == 0);
211 test_assert(strcmp(t_str_oneline("\n\r\n\r"), "") == 0);
212 test_assert(strcmp(t_str_oneline("foo"), "foo") == 0);
213 test_assert(strcmp(t_str_oneline("\nfoo"), "foo") == 0);
214 test_assert(strcmp(t_str_oneline("foo\n"), "foo") == 0);
215 test_assert(strcmp(t_str_oneline("\nfoo\n"), "foo") == 0);
216 test_assert(strcmp(t_str_oneline("foo\nbar"), "foo bar") == 0);
217 test_assert(strcmp(t_str_oneline("foo\n\nbar"), "foo bar") == 0);
218 test_assert(strcmp(t_str_oneline("\nfoo\nbar"), "foo bar") == 0);
219 test_assert(strcmp(t_str_oneline("foo\nbar\n"), "foo bar") == 0);
220 test_assert(strcmp(t_str_oneline("foo\nbar\nbaz"), "foo bar baz") == 0);
221 test_assert(strcmp(t_str_oneline("\rfoo"), "foo") == 0);
222 test_assert(strcmp(t_str_oneline("foo\r"), "foo") == 0);
223 test_assert(strcmp(t_str_oneline("\rfoo\r"), "foo") == 0);
224 test_assert(strcmp(t_str_oneline("foo\rbar"), "foobar") == 0);
225 test_assert(strcmp(t_str_oneline("foo\r\rbar"), "foobar") == 0);
226 test_assert(strcmp(t_str_oneline("\rfoo\rbar"), "foobar") == 0);
227 test_assert(strcmp(t_str_oneline("foo\rbar\r"), "foobar") == 0);
228 test_assert(strcmp(t_str_oneline("foo\rbar\rbaz"), "foobarbaz") == 0);
229 test_assert(strcmp(t_str_oneline("\r\nfoo\r\n"), "foo") == 0);
230 test_assert(strcmp(t_str_oneline("foo\r\n"), "foo") == 0);
231 test_assert(strcmp(t_str_oneline("\r\nfoo"), "foo") == 0);
232 test_assert(strcmp(t_str_oneline("foo\r\nbar"), "foo bar") == 0);
233 test_assert(strcmp(t_str_oneline("foo\r\n\r\nbar"), "foo bar") == 0);
234 test_assert(strcmp(t_str_oneline("\r\nfoo\r\nbar"), "foo bar") == 0);
235 test_assert(strcmp(t_str_oneline("foo\r\nbar\r\n"), "foo bar") == 0);
236 test_assert(strcmp(t_str_oneline("foo\r\nbar\r\nbaz"), "foo bar baz") == 0);
237 test_end();
238 }
239
test_t_str_trim(void)240 static void test_t_str_trim(void)
241 {
242 test_begin("t_str_trim");
243 test_assert(strcmp(t_str_trim("", " "), "") == 0);
244 test_assert(strcmp(t_str_trim(" ", " "), "") == 0);
245 test_assert(strcmp(t_str_trim(" \t ", "\t "), "") == 0);
246 test_assert(strcmp(t_str_trim("f \t ", "\t "), "f") == 0);
247 test_assert(strcmp(t_str_trim("foo", ""), "foo") == 0);
248 test_assert(strcmp(t_str_trim("foo", " "), "foo") == 0);
249 test_assert(strcmp(t_str_trim("foo ", " "), "foo") == 0);
250 test_assert(strcmp(t_str_trim(" foo", " "), "foo") == 0);
251 test_assert(strcmp(t_str_trim(" foo ", " "), "foo") == 0);
252 test_assert(strcmp(t_str_trim("\tfoo ", "\t "), "foo") == 0);
253 test_assert(strcmp(t_str_trim(" \tfoo\t ", "\t "), "foo") == 0);
254 test_assert(strcmp(t_str_trim("\r \tfoo\t \r", "\t \r"), "foo") == 0);
255 test_assert(strcmp(t_str_trim("\r \tfoo foo\t \r", "\t \r"), "foo foo") == 0);
256 test_assert(strcmp(t_str_trim("\tfoo\tfoo\t", "\t \r"), "foo\tfoo") == 0);
257 test_end();
258 }
259
test_t_str_ltrim(void)260 static void test_t_str_ltrim(void)
261 {
262 test_begin("t_str_ltrim");
263 test_assert(strcmp(t_str_ltrim("", " "), "") == 0);
264 test_assert(strcmp(t_str_ltrim(" ", " "), "") == 0);
265 test_assert(strcmp(t_str_ltrim(" \t ", "\t "), "") == 0);
266 test_assert(strcmp(t_str_ltrim(" \t f", "\t "), "f") == 0);
267 test_assert(strcmp(t_str_ltrim("foo", ""), "foo") == 0);
268 test_assert(strcmp(t_str_ltrim("foo", " "), "foo") == 0);
269 test_assert(strcmp(t_str_ltrim("foo ", " "), "foo ") == 0);
270 test_assert(strcmp(t_str_ltrim(" foo", " "), "foo") == 0);
271 test_assert(strcmp(t_str_ltrim(" foo ", " "), "foo ") == 0);
272 test_assert(strcmp(t_str_ltrim("\tfoo ", "\t "), "foo ") == 0);
273 test_assert(strcmp(t_str_ltrim(" \tfoo\t ", "\t "), "foo\t ") == 0);
274 test_assert(strcmp(t_str_ltrim("\r \tfoo\t \r", "\t \r"), "foo\t \r") == 0);
275 test_assert(strcmp(t_str_ltrim("\r \tfoo foo\t \r", "\t \r"), "foo foo\t \r") == 0);
276 test_assert(strcmp(t_str_ltrim("\tfoo\tfoo\t", "\t \r"), "foo\tfoo\t") == 0);
277 test_end();
278 }
279
test_t_str_rtrim(void)280 static void test_t_str_rtrim(void)
281 {
282 test_begin("t_str_rtrim");
283 test_assert(strcmp(t_str_rtrim("", " "), "") == 0);
284 test_assert(strcmp(t_str_rtrim(" ", " "), "") == 0);
285 test_assert(strcmp(t_str_rtrim(" \t ", "\t "), "") == 0);
286 test_assert(strcmp(t_str_rtrim("f \t ", "\t "), "f") == 0);
287 test_assert(strcmp(t_str_rtrim("foo", ""), "foo") == 0);
288 test_assert(strcmp(t_str_rtrim("foo", " "), "foo") == 0);
289 test_assert(strcmp(t_str_rtrim("foo ", " "), "foo") == 0);
290 test_assert(strcmp(t_str_rtrim(" foo", " "), " foo") == 0);
291 test_assert(strcmp(t_str_rtrim(" foo ", " "), " foo") == 0);
292 test_assert(strcmp(t_str_rtrim("\tfoo ", "\t "), "\tfoo") == 0);
293 test_assert(strcmp(t_str_rtrim(" \tfoo\t ", "\t "), " \tfoo") == 0);
294 test_assert(strcmp(t_str_rtrim("\r \tfoo\t \r", "\t \r"), "\r \tfoo") == 0);
295 test_assert(strcmp(t_str_rtrim("\r \tfoo foo\t \r", "\t \r"), "\r \tfoo foo") == 0);
296 test_assert(strcmp(t_str_rtrim("\tfoo\tfoo\t", "\t \r"), "\tfoo\tfoo") == 0);
297 test_end();
298 }
299
300 static const char *const test_strarray_input[] = {
301 "", "hello", "world", "", "yay", "", NULL
302 };
303 static const struct {
304 const char *separator;
305 const char *output;
306 } test_strarray_outputs[] = {
307 { "", "helloworldyay" },
308 { " ", " hello world yay " },
309 { "!-?", "!-?hello!-?world!-?!-?yay!-?" }
310 };
311
312 static const char *const test_strarray_input2[] = {
313 "", "", "hello", "world", "", "yay", "", NULL
314 };
315 static struct {
316 const char *separator;
317 const char *output;
318 } test_strarray_outputs2[] = {
319 { "", "helloworldyay" },
320 { " ", " hello world yay " },
321 { "!-?", "!-?!-?hello!-?world!-?!-?yay!-?" }
322 };
323
324 static const char *const test_strarray_input3[] = {
325 "hello", "", "", "yay", NULL
326 };
327 static struct {
328 const char *separator;
329 const char *output;
330 } test_strarray_outputs3[] = {
331 { "", "helloyay" },
332 { " ", "hello yay" },
333 { "!-?", "hello!-?!-?!-?yay" }
334 };
335
test_t_strarray_join(void)336 static void test_t_strarray_join(void)
337 {
338 const char *null = NULL;
339 unsigned int i;
340
341 test_begin("t_strarray_join()");
342
343 /* empty array -> empty string */
344 test_assert(strcmp(t_strarray_join(&null, " "), "") == 0);
345
346 for (i = 0; i < N_ELEMENTS(test_strarray_outputs); i++) {
347 test_assert_idx(strcmp(t_strarray_join(test_strarray_input,
348 test_strarray_outputs[i].separator),
349 test_strarray_outputs[i].output) == 0, i);
350 }
351 for (i = 0; i < N_ELEMENTS(test_strarray_outputs2); i++) {
352 test_assert_idx(strcmp(t_strarray_join(test_strarray_input2,
353 test_strarray_outputs2[i].separator),
354 test_strarray_outputs2[i].output) == 0, i);
355 }
356 for (i = 0; i < N_ELEMENTS(test_strarray_outputs3); i++) {
357 test_assert_idx(strcmp(t_strarray_join(test_strarray_input3,
358 test_strarray_outputs3[i].separator),
359 test_strarray_outputs3[i].output) == 0, i);
360 }
361 test_end();
362 }
363
test_p_array_const_string_join(void)364 static void test_p_array_const_string_join(void)
365 {
366 ARRAY_TYPE(const_string) arr;
367 unsigned int i;
368 char *res;
369
370 test_begin("p_array_const_string_join()");
371
372 i_array_init(&arr, 2);
373 /* empty array -> empty string */
374 test_assert(strcmp(t_array_const_string_join(&arr, " "), "") == 0);
375
376 array_append(&arr, test_strarray_input,
377 str_array_length(test_strarray_input));
378 for (i = 0; i < N_ELEMENTS(test_strarray_outputs); i++) {
379 res = p_array_const_string_join(default_pool, &arr,
380 test_strarray_outputs[i].separator);
381 test_assert_idx(strcmp(res, test_strarray_outputs[i].output) == 0, i);
382 i_free(res);
383 }
384
385 array_free(&arr);
386 test_end();
387 }
388
test_mem_equals_timing_safe(void)389 static void test_mem_equals_timing_safe(void)
390 {
391 const struct {
392 const char *a, *b;
393 } tests[] = {
394 { "", "" },
395 { "a", "a" },
396 { "b", "a" },
397 { "ab", "ab" },
398 { "ab", "ba" },
399 { "ab", "bc" },
400 };
401 test_begin("mem_equals_timing_safe()");
402 for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) {
403 size_t len = strlen(tests[i].a);
404 i_assert(len == strlen(tests[i].b));
405 test_assert((memcmp(tests[i].a, tests[i].b, len) == 0) ==
406 mem_equals_timing_safe(tests[i].a, tests[i].b, len));
407 test_assert((memcmp(tests[i].a, tests[i].b, len) == 0) ==
408 mem_equals_timing_safe(tests[i].b, tests[i].a, len));
409 }
410 test_end();
411 }
412
test_str_equals_timing_almost_safe(void)413 static void test_str_equals_timing_almost_safe(void)
414 {
415 const struct {
416 const char *a, *b;
417 } tests[] = {
418 { "", "" },
419 { "a", "a" },
420 { "b", "a" },
421 { "ab", "ab" },
422 { "ab", "ba" },
423 { "ab", "bc" },
424 { "a", "" },
425 { "a", "ab" },
426 { "a", "abc" },
427 { "ab", "abc" },
428 };
429 test_begin("str_equals_timing_almost_safe()");
430 for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) {
431 test_assert((strcmp(tests[i].a, tests[i].b) == 0) ==
432 str_equals_timing_almost_safe(tests[i].a, tests[i].b));
433 test_assert((strcmp(tests[i].a, tests[i].b) == 0) ==
434 str_equals_timing_almost_safe(tests[i].b, tests[i].a));
435 }
436 test_end();
437 }
438
test_dec2str_buf(void)439 static void test_dec2str_buf(void)
440 {
441 const uintmax_t test_input[] = {
442 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
443 99, 999, 9999, 65535, 65536, 99999, 999999, 9999999,
444 99999999, 999999999, 4294967295, 4294967296ULL,
445 9999999999999999999ULL,
446 18446744073709551615ULL
447 };
448 char buf[MAX_INT_STRLEN], buf2[MAX_INT_STRLEN];
449
450 test_begin("dec2str_buf()");
451 for (unsigned int i = 0; i < N_ELEMENTS(test_input); i++) {
452 i_snprintf(buf2, sizeof(buf2), "%ju", test_input[i]);
453 test_assert_idx(strcmp(dec2str_buf(buf, test_input[i]),
454 buf2) == 0, i);
455 }
456 test_end();
457 }
458
459 static void
test_str_match(void)460 test_str_match(void)
461 {
462 static const struct {
463 const char*s1, *s2; size_t match;
464 } tests[] = {
465 #define MATCH_TEST(common, left, right) { common left, common right, sizeof(common)-1 }
466 MATCH_TEST("", "", ""),
467 MATCH_TEST("", "x", ""),
468 MATCH_TEST("", "", "x"),
469 MATCH_TEST("", "foo", "bar"),
470 MATCH_TEST("x", "", ""),
471 MATCH_TEST("x", "y", "z"),
472 MATCH_TEST("blahblahblah", "", ""),
473 MATCH_TEST("blahblahblah", "", "bar"),
474 MATCH_TEST("blahblahblah", "foo", ""),
475 MATCH_TEST("blahblahblah", "foo", "bar"),
476 #undef MATCH_TEST
477 };
478
479 unsigned int i;
480
481 test_begin("str_match");
482 for (i = 0; i < N_ELEMENTS(tests); i++)
483 test_assert_idx(str_match(tests[i].s1, tests[i].s2) == tests[i].match, i);
484 test_end();
485
486 test_begin("str_begins");
487 for (i = 0; i < N_ELEMENTS(tests); i++) {
488 /* This is just 2 ways of wording the same test, but that also
489 sanity tests the match values above. */
490 test_assert_idx(str_begins(tests[i].s1, tests[i].s2) ==
491 (str_begins(tests[i].s1, tests[i].s2)), i);
492 test_assert_idx(str_begins(tests[i].s1, tests[i].s2) ==
493 (strlen(tests[i].s2) == tests[i].match), i);
494 }
495 test_end();
496 }
497
test_memspn(void)498 static void test_memspn(void)
499 {
500 #undef TEST_CASE
501 /* we substract 1 to ensure we don't include the final \0 byte */
502 #define TEST_CASE(a, b, r) { \
503 .input = (const unsigned char*)((a)), .input_len = sizeof((a))-1, \
504 .accept = (const unsigned char*)((b)), .accept_len = sizeof((b))-1, \
505 .result = r, \
506 }
507
508 static struct {
509 const unsigned char *input;
510 size_t input_len;
511 const unsigned char *accept;
512 size_t accept_len;
513 size_t result;
514 } tests[] = {
515 TEST_CASE("", "", 0),
516 TEST_CASE("", "123456789", 0),
517 TEST_CASE("123456789", "", 0),
518 TEST_CASE("hello, world", "helo", 5),
519 TEST_CASE("hello, uuuuu", "helo", 5),
520 TEST_CASE("\0\0\0\0\0hello", "\0", 5),
521 TEST_CASE("\r\r\r\r", "\r", 4),
522 TEST_CASE("aaa", "a", 3),
523 TEST_CASE("bbb", "a", 0),
524 /* null safety test */
525 {
526 .input = NULL, .accept = NULL,
527 .input_len = 0, .accept_len = 0,
528 .result = 0,
529 }
530 };
531
532 test_begin("i_memspn");
533
534 for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) {
535 size_t a = i_memspn(tests[i].input, tests[i].input_len,
536 tests[i].accept, tests[i].accept_len);
537 test_assert_ucmp_idx(a, ==, tests[i].result, i);
538 if (tests[i].input == NULL)
539 continue;
540 a = i_memspn(tests[i].input, strlen((const char*)tests[i].input),
541 tests[i].accept, strlen((const char*)tests[i].accept));
542 size_t b = strspn((const char*)tests[i].input,
543 (const char*)tests[i].accept);
544 test_assert_ucmp_idx(a, ==, b, i);
545 }
546
547 test_end();
548 }
549
test_memcspn(void)550 static void test_memcspn(void)
551 {
552 #undef TEST_CASE
553 /* we substract 1 to ensure we don't include the final \0 byte */
554 #define TEST_CASE(a, b, r) { \
555 .input = (const unsigned char*)((a)), .input_len = sizeof((a))-1, \
556 .reject = (const unsigned char*)((b)), .reject_len = sizeof((b))-1, \
557 .result = r, \
558 }
559
560 static struct {
561 const unsigned char *input;
562 size_t input_len;
563 const unsigned char *reject;
564 size_t reject_len;
565 size_t result;
566 } tests[] = {
567 TEST_CASE("", "", 0),
568 TEST_CASE("hello", "", 5),
569 TEST_CASE("uuuuu, hello", "helo", 7),
570 TEST_CASE("\0\0\0\0\0\0hello", "u", 11),
571 TEST_CASE("this\0is\0test", "\0", 4),
572 TEST_CASE("hello, world\r", "\r", 12),
573 TEST_CASE("aaa", "a", 0),
574 TEST_CASE("bbb", "a", 3),
575 /* null safety test */
576 {
577 .input = NULL, .reject = NULL,
578 .input_len = 0, .reject_len = 0,
579 .result = 0,
580 }
581 };
582
583 test_begin("i_memcspn");
584
585 for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) {
586 size_t a = i_memcspn(tests[i].input, tests[i].input_len,
587 tests[i].reject, tests[i].reject_len);
588 test_assert_ucmp_idx(a, ==, tests[i].result, i);
589 if (tests[i].input == NULL)
590 continue;
591 a = i_memcspn(tests[i].input, strlen((const char*)tests[i].input),
592 tests[i].reject, strlen((const char*)tests[i].reject));
593 size_t b = strcspn((const char*)tests[i].input,
594 (const char*)tests[i].reject);
595 test_assert_ucmp_idx(a, ==, b, i);
596 }
597
598 test_end();
599 }
600
test_strfuncs(void)601 void test_strfuncs(void)
602 {
603 test_p_strdup();
604 test_p_strndup();
605 test_p_strdup_empty();
606 test_p_strdup_until();
607 test_p_strarray_dup();
608 test_t_strsplit();
609 test_t_strsplit_spaces();
610 test_t_str_replace();
611 test_t_str_oneline();
612 test_t_str_trim();
613 test_t_str_ltrim();
614 test_t_str_rtrim();
615 test_t_strarray_join();
616 test_p_array_const_string_join();
617 test_mem_equals_timing_safe();
618 test_str_equals_timing_almost_safe();
619 test_dec2str_buf();
620 test_str_match();
621 test_memspn();
622 test_memcspn();
623 }
624
fatal_strfuncs(unsigned int stage)625 enum fatal_test_state fatal_strfuncs(unsigned int stage)
626 {
627 switch (stage) {
628 case 0:
629 test_begin("fatal p_strndup()");
630 test_expect_fatal_string("(str != NULL)");
631 (void)p_strndup(default_pool, NULL, 100);
632 return FATAL_TEST_FAILURE;
633 case 1:
634 test_expect_fatal_string("(max_chars != SIZE_MAX)");
635 (void)p_strndup(default_pool, "foo", SIZE_MAX);
636 return FATAL_TEST_FAILURE;
637 }
638 test_end();
639 return FATAL_TEST_FINISHED;
640 }
641