From: Timo Sirainen Date: Thu, 11 Mar 2021 23:19:38 +0000 (+0200) Subject: lib: Optimize p_strndup() X-Git-Tag: 2.3.17~101 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=de0871dedb4a06882e8a53ae80bb656d8db6752d;p=thirdparty%2Fdovecot%2Fcore.git lib: Optimize p_strndup() --- diff --git a/src/lib/strfuncs.c b/src/lib/strfuncs.c index 7b5e54499a..68b67a2fb4 100644 --- a/src/lib/strfuncs.c +++ b/src/lib/strfuncs.c @@ -87,19 +87,21 @@ char *p_strdup_until(pool_t pool, const void *start, const void *end) char *p_strndup(pool_t pool, const void *str, size_t max_chars) { + const char *p; char *mem; size_t len; i_assert(str != NULL); i_assert(max_chars != SIZE_MAX); - len = 0; - while (len < max_chars && ((const char *) str)[len] != '\0') - len++; + p = memchr(str, '\0', max_chars); + if (p == NULL) + len = max_chars; + else + len = p - (const char *)str; mem = p_malloc(pool, len+1); memcpy(mem, str, len); - mem[len] = '\0'; return mem; } diff --git a/src/lib/test-lib.inc b/src/lib/test-lib.inc index 0591f86dc3..549c7bd4e1 100644 --- a/src/lib/test-lib.inc +++ b/src/lib/test-lib.inc @@ -95,6 +95,7 @@ TEST(test_stats_dist) TEST(test_str) TEST(test_strescape) TEST(test_strfuncs) +FATAL(fatal_strfuncs) TEST(test_strnum) TEST(test_str_find) TEST(test_str_sanitize) diff --git a/src/lib/test-strfuncs.c b/src/lib/test-strfuncs.c index 5db2711037..b3c84fee7c 100644 --- a/src/lib/test-strfuncs.c +++ b/src/lib/test-strfuncs.c @@ -16,6 +16,29 @@ static void test_p_strdup(void) 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", "foo", SIZE_MAX-1 }, + }; + 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()"); @@ -475,6 +498,7 @@ test_str_match(void) void test_strfuncs(void) { test_p_strdup(); + test_p_strndup(); test_p_strdup_empty(); test_p_strdup_until(); test_p_strarray_dup(); @@ -492,3 +516,20 @@ void test_strfuncs(void) test_dec2str_buf(); test_str_match(); } + +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; +}