diff options
Diffstat (limited to 'src/lib/test-strfuncs.c')
-rw-r--r-- | src/lib/test-strfuncs.c | 640 |
1 files changed, 640 insertions, 0 deletions
diff --git a/src/lib/test-strfuncs.c b/src/lib/test-strfuncs.c new file mode 100644 index 0000000..b546384 --- /dev/null +++ b/src/lib/test-strfuncs.c @@ -0,0 +1,640 @@ +/* Copyright (c) 2009-2018 Dovecot authors, see the included COPYING file */ + +#include "test-lib.h" +#include "array.h" + +static void test_p_strdup(void) +{ + test_begin("p_strdup()"); + test_assert(p_strdup(default_pool, NULL) == NULL); + + const char *src = "foo"; + char *str = p_strdup(default_pool, src); + test_assert(str != src && str != NULL && strcmp(src, str) == 0); + p_free(default_pool, str); + + test_end(); +} + +static void test_p_strndup(void) +{ + struct { + const char *input; + const char *output; + size_t len; + } tests[] = { + { "foo", "fo", 2 }, + { "foo", "foo", 3 }, + { "foo", "foo", 4 }, + { "foo\0more", "foo", 8 }, + }; + test_begin("p_strndup()"); + + for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) { + char *str = p_strndup(default_pool, tests[i].input, + tests[i].len); + test_assert_strcmp_idx(str, tests[i].output, i); + p_free(default_pool, str); + } + test_end(); +} + +static void test_p_strdup_empty(void) +{ + test_begin("p_strdup_empty()"); + test_assert(p_strdup_empty(default_pool, NULL) == NULL); + test_assert(p_strdup_empty(default_pool, "") == NULL); + + const char *src = "foo"; + char *str = p_strdup_empty(default_pool, src); + test_assert(str != src && str != NULL && strcmp(src, str) == 0); + p_free(default_pool, str); + + test_end(); +} + +static void test_p_strdup_until(void) +{ + const char src[] = "foo\0bar"; + char *str; + + test_begin("p_strdup_until()"); + str = p_strdup_until(default_pool, src, src+2); + test_assert(strcmp(str, "fo") == 0); + p_free(default_pool, str); + + str = p_strdup_until(default_pool, src, src+3); + test_assert(strcmp(str, "foo") == 0); + p_free(default_pool, str); + + /* \0 is ignored */ + str = p_strdup_until(default_pool, src, src+7); + test_assert(memcmp(str, src, sizeof(src)) == 0); + p_free(default_pool, str); + + str = p_strdup_until(default_pool, src, src+8); + test_assert(memcmp(str, src, sizeof(src)) == 0); + p_free(default_pool, str); + + test_end(); +} + +static void test_p_strarray_dup(void) +{ + const char *input[][3] = { + { NULL }, + { "a", NULL }, + { "foobar", NULL }, + { "a", "foo", NULL } + }; + const char **ret; + unsigned int i, j; + + test_begin("p_strarray_dup"); + + for (i = 0; i < N_ELEMENTS(input); i++) { + ret = p_strarray_dup(default_pool, input[i]); + for (j = 0; input[i][j] != NULL; j++) { + test_assert(strcmp(input[i][j], ret[j]) == 0); + test_assert(input[i][j] != ret[j]); + } + test_assert(ret[j] == NULL); + i_free(ret); + } + test_end(); +} + +static void test_t_strsplit(void) +{ + struct { + const char *input; + const char *const *output; + } tests[] = { + /* empty string -> empty array. was this perhaps a mistake for + the API to do this originally?.. can't really change now + anyway. */ + { "", (const char *const []) { NULL } }, + { "\n", (const char *const []) { "", "", NULL } }, + { "\n\n", (const char *const []) { "", "", "", NULL } }, + { "foo", (const char *const []) { "foo", NULL } }, + { "foo\n", (const char *const []) { "foo", "", NULL } }, + { "foo\nbar", (const char *const []) { "foo", "bar", NULL } }, + { "foo\nbar\n", (const char *const []) { "foo", "bar", "", NULL } }, + { "\nfoo\n\nbar\n\n", (const char *const []) { "", "foo", "", "bar", "", "", NULL } }, + }; + const char *const *args, *const *args2, *const *args3; + + test_begin("t_strsplit"); + + for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) { + /* split_str_fast() with single separator */ + args = t_strsplit(tests[i].input, "\n"); + /* split_str_slow() with a secondary separator */ + args2 = t_strsplit(tests[i].input, "\r\n"); + /* also as suffix */ + args3 = t_strsplit(tests[i].input, "\n\r"); + for (unsigned int j = 0; tests[i].output[j] != NULL; j++) { + test_assert_idx(null_strcmp(tests[i].output[j], args[j]) == 0, i); + test_assert_idx(null_strcmp(args[j], args2[j]) == 0, i); + test_assert_idx(null_strcmp(args[j], args3[j]) == 0, i); + } + } + test_end(); +} + +static void test_t_strsplit_spaces(void) +{ + struct { + const char *input; + const char *const *output; + } tests[] = { + /* empty strings */ + { "", (const char *const []) { NULL } }, + { "\n", (const char *const []) { NULL } }, + { "\n\n", (const char *const []) { NULL } }, + /* normal */ + { "foo", (const char *const []) { "foo", NULL } }, + { "foo\n", (const char *const []) { "foo", NULL } }, + { "foo\nbar", (const char *const []) { "foo", "bar", NULL } }, + { "foo\nbar\n", (const char *const []) { "foo", "bar", NULL } }, + { "\nfoo\n\nbar\n\n", (const char *const []) { "foo", "bar", NULL } }, + }; + const char *const *args, *const *args2, *const *args3; + + test_begin("t_strsplit_spaces"); + + for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) { + args = t_strsplit_spaces(tests[i].input, "\n"); + /* test also with a secondary nonexistent separator */ + args2 = t_strsplit_spaces(tests[i].input, "\r\n"); + /* also as suffix */ + args3 = t_strsplit_spaces(tests[i].input, "\n\r"); + for (unsigned int j = 0; tests[i].output[j] != NULL; j++) { + test_assert_idx(null_strcmp(tests[i].output[j], args[j]) == 0, i); + test_assert_idx(null_strcmp(args[j], args2[j]) == 0, i); + test_assert_idx(null_strcmp(args[j], args3[j]) == 0, i); + } + } + + /* multiple separators */ + args = t_strsplit_spaces(" , , ,str1 , ,,, , str2 , ", " ,"); + test_assert(strcmp(args[0], "str1") == 0); + test_assert(strcmp(args[1], "str2") == 0); + test_assert(args[2] == NULL); + test_end(); +} + +static void test_t_str_replace(void) +{ + test_begin("t_str_replace"); + test_assert(strcmp(t_str_replace("foo", 'a', 'b'), "foo") == 0); + test_assert(strcmp(t_str_replace("fooa", 'a', 'b'), "foob") == 0); + test_assert(strcmp(t_str_replace("afooa", 'a', 'b'), "bfoob") == 0); + test_assert(strcmp(t_str_replace("", 'a', 'b'), "") == 0); + test_assert(strcmp(t_str_replace("a", 'a', 'b'), "b") == 0); + test_assert(strcmp(t_str_replace("aaa", 'a', 'b'), "bbb") == 0); + test_assert(strcmp(t_str_replace("bbb", 'a', 'b'), "bbb") == 0); + test_assert(strcmp(t_str_replace("aba", 'a', 'b'), "bbb") == 0); + test_end(); +} + +static void test_t_str_oneline(void) +{ + test_begin("t_str_oneline"); + test_assert(strcmp(t_str_oneline("\n"), "") == 0); + test_assert(strcmp(t_str_oneline("\r"), "") == 0); + test_assert(strcmp(t_str_oneline("\n\n"), "") == 0); + test_assert(strcmp(t_str_oneline("\r\r"), "") == 0); + test_assert(strcmp(t_str_oneline("\r\n"), "") == 0); + test_assert(strcmp(t_str_oneline("\r\n\r\n"), "") == 0); + test_assert(strcmp(t_str_oneline("\n\r"), "") == 0); + test_assert(strcmp(t_str_oneline("\n\r\n\r"), "") == 0); + test_assert(strcmp(t_str_oneline("foo"), "foo") == 0); + test_assert(strcmp(t_str_oneline("\nfoo"), "foo") == 0); + test_assert(strcmp(t_str_oneline("foo\n"), "foo") == 0); + test_assert(strcmp(t_str_oneline("\nfoo\n"), "foo") == 0); + test_assert(strcmp(t_str_oneline("foo\nbar"), "foo bar") == 0); + test_assert(strcmp(t_str_oneline("foo\n\nbar"), "foo bar") == 0); + test_assert(strcmp(t_str_oneline("\nfoo\nbar"), "foo bar") == 0); + test_assert(strcmp(t_str_oneline("foo\nbar\n"), "foo bar") == 0); + test_assert(strcmp(t_str_oneline("foo\nbar\nbaz"), "foo bar baz") == 0); + test_assert(strcmp(t_str_oneline("\rfoo"), "foo") == 0); + test_assert(strcmp(t_str_oneline("foo\r"), "foo") == 0); + test_assert(strcmp(t_str_oneline("\rfoo\r"), "foo") == 0); + test_assert(strcmp(t_str_oneline("foo\rbar"), "foobar") == 0); + test_assert(strcmp(t_str_oneline("foo\r\rbar"), "foobar") == 0); + test_assert(strcmp(t_str_oneline("\rfoo\rbar"), "foobar") == 0); + test_assert(strcmp(t_str_oneline("foo\rbar\r"), "foobar") == 0); + test_assert(strcmp(t_str_oneline("foo\rbar\rbaz"), "foobarbaz") == 0); + test_assert(strcmp(t_str_oneline("\r\nfoo\r\n"), "foo") == 0); + test_assert(strcmp(t_str_oneline("foo\r\n"), "foo") == 0); + test_assert(strcmp(t_str_oneline("\r\nfoo"), "foo") == 0); + test_assert(strcmp(t_str_oneline("foo\r\nbar"), "foo bar") == 0); + test_assert(strcmp(t_str_oneline("foo\r\n\r\nbar"), "foo bar") == 0); + test_assert(strcmp(t_str_oneline("\r\nfoo\r\nbar"), "foo bar") == 0); + test_assert(strcmp(t_str_oneline("foo\r\nbar\r\n"), "foo bar") == 0); + test_assert(strcmp(t_str_oneline("foo\r\nbar\r\nbaz"), "foo bar baz") == 0); + test_end(); +} + +static void test_t_str_trim(void) +{ + test_begin("t_str_trim"); + test_assert(strcmp(t_str_trim("", " "), "") == 0); + test_assert(strcmp(t_str_trim(" ", " "), "") == 0); + test_assert(strcmp(t_str_trim(" \t ", "\t "), "") == 0); + test_assert(strcmp(t_str_trim("f \t ", "\t "), "f") == 0); + test_assert(strcmp(t_str_trim("foo", ""), "foo") == 0); + test_assert(strcmp(t_str_trim("foo", " "), "foo") == 0); + test_assert(strcmp(t_str_trim("foo ", " "), "foo") == 0); + test_assert(strcmp(t_str_trim(" foo", " "), "foo") == 0); + test_assert(strcmp(t_str_trim(" foo ", " "), "foo") == 0); + test_assert(strcmp(t_str_trim("\tfoo ", "\t "), "foo") == 0); + test_assert(strcmp(t_str_trim(" \tfoo\t ", "\t "), "foo") == 0); + test_assert(strcmp(t_str_trim("\r \tfoo\t \r", "\t \r"), "foo") == 0); + test_assert(strcmp(t_str_trim("\r \tfoo foo\t \r", "\t \r"), "foo foo") == 0); + test_assert(strcmp(t_str_trim("\tfoo\tfoo\t", "\t \r"), "foo\tfoo") == 0); + test_end(); +} + +static void test_t_str_ltrim(void) +{ + test_begin("t_str_ltrim"); + test_assert(strcmp(t_str_ltrim("", " "), "") == 0); + test_assert(strcmp(t_str_ltrim(" ", " "), "") == 0); + test_assert(strcmp(t_str_ltrim(" \t ", "\t "), "") == 0); + test_assert(strcmp(t_str_ltrim(" \t f", "\t "), "f") == 0); + test_assert(strcmp(t_str_ltrim("foo", ""), "foo") == 0); + test_assert(strcmp(t_str_ltrim("foo", " "), "foo") == 0); + test_assert(strcmp(t_str_ltrim("foo ", " "), "foo ") == 0); + test_assert(strcmp(t_str_ltrim(" foo", " "), "foo") == 0); + test_assert(strcmp(t_str_ltrim(" foo ", " "), "foo ") == 0); + test_assert(strcmp(t_str_ltrim("\tfoo ", "\t "), "foo ") == 0); + test_assert(strcmp(t_str_ltrim(" \tfoo\t ", "\t "), "foo\t ") == 0); + test_assert(strcmp(t_str_ltrim("\r \tfoo\t \r", "\t \r"), "foo\t \r") == 0); + test_assert(strcmp(t_str_ltrim("\r \tfoo foo\t \r", "\t \r"), "foo foo\t \r") == 0); + test_assert(strcmp(t_str_ltrim("\tfoo\tfoo\t", "\t \r"), "foo\tfoo\t") == 0); + test_end(); +} + +static void test_t_str_rtrim(void) +{ + test_begin("t_str_rtrim"); + test_assert(strcmp(t_str_rtrim("", " "), "") == 0); + test_assert(strcmp(t_str_rtrim(" ", " "), "") == 0); + test_assert(strcmp(t_str_rtrim(" \t ", "\t "), "") == 0); + test_assert(strcmp(t_str_rtrim("f \t ", "\t "), "f") == 0); + test_assert(strcmp(t_str_rtrim("foo", ""), "foo") == 0); + test_assert(strcmp(t_str_rtrim("foo", " "), "foo") == 0); + test_assert(strcmp(t_str_rtrim("foo ", " "), "foo") == 0); + test_assert(strcmp(t_str_rtrim(" foo", " "), " foo") == 0); + test_assert(strcmp(t_str_rtrim(" foo ", " "), " foo") == 0); + test_assert(strcmp(t_str_rtrim("\tfoo ", "\t "), "\tfoo") == 0); + test_assert(strcmp(t_str_rtrim(" \tfoo\t ", "\t "), " \tfoo") == 0); + test_assert(strcmp(t_str_rtrim("\r \tfoo\t \r", "\t \r"), "\r \tfoo") == 0); + test_assert(strcmp(t_str_rtrim("\r \tfoo foo\t \r", "\t \r"), "\r \tfoo foo") == 0); + test_assert(strcmp(t_str_rtrim("\tfoo\tfoo\t", "\t \r"), "\tfoo\tfoo") == 0); + test_end(); +} + +static const char *const test_strarray_input[] = { + "", "hello", "world", "", "yay", "", NULL +}; +static const struct { + const char *separator; + const char *output; +} test_strarray_outputs[] = { + { "", "helloworldyay" }, + { " ", " hello world yay " }, + { "!-?", "!-?hello!-?world!-?!-?yay!-?" } +}; + +static const char *const test_strarray_input2[] = { + "", "", "hello", "world", "", "yay", "", NULL +}; +static struct { + const char *separator; + const char *output; +} test_strarray_outputs2[] = { + { "", "helloworldyay" }, + { " ", " hello world yay " }, + { "!-?", "!-?!-?hello!-?world!-?!-?yay!-?" } +}; + +static const char *const test_strarray_input3[] = { + "hello", "", "", "yay", NULL +}; +static struct { + const char *separator; + const char *output; +} test_strarray_outputs3[] = { + { "", "helloyay" }, + { " ", "hello yay" }, + { "!-?", "hello!-?!-?!-?yay" } +}; + +static void test_t_strarray_join(void) +{ + const char *null = NULL; + unsigned int i; + + test_begin("t_strarray_join()"); + + /* empty array -> empty string */ + test_assert(strcmp(t_strarray_join(&null, " "), "") == 0); + + for (i = 0; i < N_ELEMENTS(test_strarray_outputs); i++) { + test_assert_idx(strcmp(t_strarray_join(test_strarray_input, + test_strarray_outputs[i].separator), + test_strarray_outputs[i].output) == 0, i); + } + for (i = 0; i < N_ELEMENTS(test_strarray_outputs2); i++) { + test_assert_idx(strcmp(t_strarray_join(test_strarray_input2, + test_strarray_outputs2[i].separator), + test_strarray_outputs2[i].output) == 0, i); + } + for (i = 0; i < N_ELEMENTS(test_strarray_outputs3); i++) { + test_assert_idx(strcmp(t_strarray_join(test_strarray_input3, + test_strarray_outputs3[i].separator), + test_strarray_outputs3[i].output) == 0, i); + } + test_end(); +} + +static void test_p_array_const_string_join(void) +{ + ARRAY_TYPE(const_string) arr; + unsigned int i; + char *res; + + test_begin("p_array_const_string_join()"); + + i_array_init(&arr, 2); + /* empty array -> empty string */ + test_assert(strcmp(t_array_const_string_join(&arr, " "), "") == 0); + + array_append(&arr, test_strarray_input, + str_array_length(test_strarray_input)); + for (i = 0; i < N_ELEMENTS(test_strarray_outputs); i++) { + res = p_array_const_string_join(default_pool, &arr, + test_strarray_outputs[i].separator); + test_assert_idx(strcmp(res, test_strarray_outputs[i].output) == 0, i); + i_free(res); + } + + array_free(&arr); + test_end(); +} + +static void test_mem_equals_timing_safe(void) +{ + const struct { + const char *a, *b; + } tests[] = { + { "", "" }, + { "a", "a" }, + { "b", "a" }, + { "ab", "ab" }, + { "ab", "ba" }, + { "ab", "bc" }, + }; + test_begin("mem_equals_timing_safe()"); + for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) { + size_t len = strlen(tests[i].a); + i_assert(len == strlen(tests[i].b)); + test_assert((memcmp(tests[i].a, tests[i].b, len) == 0) == + mem_equals_timing_safe(tests[i].a, tests[i].b, len)); + test_assert((memcmp(tests[i].a, tests[i].b, len) == 0) == + mem_equals_timing_safe(tests[i].b, tests[i].a, len)); + } + test_end(); +} + +static void test_str_equals_timing_almost_safe(void) +{ + const struct { + const char *a, *b; + } tests[] = { + { "", "" }, + { "a", "a" }, + { "b", "a" }, + { "ab", "ab" }, + { "ab", "ba" }, + { "ab", "bc" }, + { "a", "" }, + { "a", "ab" }, + { "a", "abc" }, + { "ab", "abc" }, + }; + test_begin("str_equals_timing_almost_safe()"); + for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) { + test_assert((strcmp(tests[i].a, tests[i].b) == 0) == + str_equals_timing_almost_safe(tests[i].a, tests[i].b)); + test_assert((strcmp(tests[i].a, tests[i].b) == 0) == + str_equals_timing_almost_safe(tests[i].b, tests[i].a)); + } + test_end(); +} + +static void test_dec2str_buf(void) +{ + const uintmax_t test_input[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 99, 999, 9999, 65535, 65536, 99999, 999999, 9999999, + 99999999, 999999999, 4294967295, 4294967296ULL, + 9999999999999999999ULL, + 18446744073709551615ULL + }; + char buf[MAX_INT_STRLEN], buf2[MAX_INT_STRLEN]; + + test_begin("dec2str_buf()"); + for (unsigned int i = 0; i < N_ELEMENTS(test_input); i++) { + i_snprintf(buf2, sizeof(buf2), "%ju", test_input[i]); + test_assert_idx(strcmp(dec2str_buf(buf, test_input[i]), + buf2) == 0, i); + } + test_end(); +} + +static void +test_str_match(void) +{ + static const struct { + const char*s1, *s2; size_t match; + } tests[] = { +#define MATCH_TEST(common, left, right) { common left, common right, sizeof(common)-1 } + MATCH_TEST("", "", ""), + MATCH_TEST("", "x", ""), + MATCH_TEST("", "", "x"), + MATCH_TEST("", "foo", "bar"), + MATCH_TEST("x", "", ""), + MATCH_TEST("x", "y", "z"), + MATCH_TEST("blahblahblah", "", ""), + MATCH_TEST("blahblahblah", "", "bar"), + MATCH_TEST("blahblahblah", "foo", ""), + MATCH_TEST("blahblahblah", "foo", "bar"), +#undef MATCH_TEST + }; + + unsigned int i; + + test_begin("str_match"); + for (i = 0; i < N_ELEMENTS(tests); i++) + test_assert_idx(str_match(tests[i].s1, tests[i].s2) == tests[i].match, i); + test_end(); + + test_begin("str_begins"); + for (i = 0; i < N_ELEMENTS(tests); i++) { + /* This is just 2 ways of wording the same test, but that also + sanity tests the match values above. */ + test_assert_idx(str_begins(tests[i].s1, tests[i].s2) == + (str_begins(tests[i].s1, tests[i].s2)), i); + test_assert_idx(str_begins(tests[i].s1, tests[i].s2) == + (strlen(tests[i].s2) == tests[i].match), i); + } + test_end(); +} + +static void test_memspn(void) +{ +#undef TEST_CASE +/* we substract 1 to ensure we don't include the final \0 byte */ +#define TEST_CASE(a, b, r) { \ + .input = (const unsigned char*)((a)), .input_len = sizeof((a))-1, \ + .accept = (const unsigned char*)((b)), .accept_len = sizeof((b))-1, \ + .result = r, \ +} + + static struct { + const unsigned char *input; + size_t input_len; + const unsigned char *accept; + size_t accept_len; + size_t result; + } tests[] = { + TEST_CASE("", "", 0), + TEST_CASE("", "123456789", 0), + TEST_CASE("123456789", "", 0), + TEST_CASE("hello, world", "helo", 5), + TEST_CASE("hello, uuuuu", "helo", 5), + TEST_CASE("\0\0\0\0\0hello", "\0", 5), + TEST_CASE("\r\r\r\r", "\r", 4), + TEST_CASE("aaa", "a", 3), + TEST_CASE("bbb", "a", 0), + /* null safety test */ + { + .input = NULL, .accept = NULL, + .input_len = 0, .accept_len = 0, + .result = 0, + } + }; + + test_begin("i_memspn"); + + for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) { + size_t a = i_memspn(tests[i].input, tests[i].input_len, + tests[i].accept, tests[i].accept_len); + test_assert_ucmp_idx(a, ==, tests[i].result, i); + if (tests[i].input == NULL) + continue; + a = i_memspn(tests[i].input, strlen((const char*)tests[i].input), + tests[i].accept, strlen((const char*)tests[i].accept)); + size_t b = strspn((const char*)tests[i].input, + (const char*)tests[i].accept); + test_assert_ucmp_idx(a, ==, b, i); + } + + test_end(); +} + +static void test_memcspn(void) +{ +#undef TEST_CASE +/* we substract 1 to ensure we don't include the final \0 byte */ +#define TEST_CASE(a, b, r) { \ + .input = (const unsigned char*)((a)), .input_len = sizeof((a))-1, \ + .reject = (const unsigned char*)((b)), .reject_len = sizeof((b))-1, \ + .result = r, \ +} + + static struct { + const unsigned char *input; + size_t input_len; + const unsigned char *reject; + size_t reject_len; + size_t result; + } tests[] = { + TEST_CASE("", "", 0), + TEST_CASE("hello", "", 5), + TEST_CASE("uuuuu, hello", "helo", 7), + TEST_CASE("\0\0\0\0\0\0hello", "u", 11), + TEST_CASE("this\0is\0test", "\0", 4), + TEST_CASE("hello, world\r", "\r", 12), + TEST_CASE("aaa", "a", 0), + TEST_CASE("bbb", "a", 3), + /* null safety test */ + { + .input = NULL, .reject = NULL, + .input_len = 0, .reject_len = 0, + .result = 0, + } + }; + + test_begin("i_memcspn"); + + for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) { + size_t a = i_memcspn(tests[i].input, tests[i].input_len, + tests[i].reject, tests[i].reject_len); + test_assert_ucmp_idx(a, ==, tests[i].result, i); + if (tests[i].input == NULL) + continue; + a = i_memcspn(tests[i].input, strlen((const char*)tests[i].input), + tests[i].reject, strlen((const char*)tests[i].reject)); + size_t b = strcspn((const char*)tests[i].input, + (const char*)tests[i].reject); + test_assert_ucmp_idx(a, ==, b, i); + } + + test_end(); +} + +void test_strfuncs(void) +{ + test_p_strdup(); + test_p_strndup(); + test_p_strdup_empty(); + test_p_strdup_until(); + test_p_strarray_dup(); + test_t_strsplit(); + test_t_strsplit_spaces(); + test_t_str_replace(); + test_t_str_oneline(); + test_t_str_trim(); + test_t_str_ltrim(); + test_t_str_rtrim(); + test_t_strarray_join(); + test_p_array_const_string_join(); + test_mem_equals_timing_safe(); + test_str_equals_timing_almost_safe(); + test_dec2str_buf(); + test_str_match(); + test_memspn(); + test_memcspn(); +} + +enum fatal_test_state fatal_strfuncs(unsigned int stage) +{ + switch (stage) { + case 0: + test_begin("fatal p_strndup()"); + test_expect_fatal_string("(str != NULL)"); + (void)p_strndup(default_pool, NULL, 100); + return FATAL_TEST_FAILURE; + case 1: + test_expect_fatal_string("(max_chars != SIZE_MAX)"); + (void)p_strndup(default_pool, "foo", SIZE_MAX); + return FATAL_TEST_FAILURE; + } + test_end(); + return FATAL_TEST_FINISHED; +} |