From: Timo Sirainen Date: Thu, 24 Oct 2019 08:43:58 +0000 (+0300) Subject: lib-imap: imap_write_arg() - minor optimization to IMAP_ARG_STRING X-Git-Tag: 2.3.10~135 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=60dcd370e6373a5afd1a0862d19040355b9b95b0;p=thirdparty%2Fdovecot%2Fcore.git lib-imap: imap_write_arg() - minor optimization to IMAP_ARG_STRING Avoid unnecessarily using data stack. Also add unit tests to imap_write_arg(). --- diff --git a/src/lib-imap/imap-util.c b/src/lib-imap/imap-util.c index 34ebe5d203..b6d4258131 100644 --- a/src/lib-imap/imap-util.c +++ b/src/lib-imap/imap-util.c @@ -83,11 +83,13 @@ void imap_write_arg(string_t *dest, const struct imap_arg *arg) case IMAP_ARG_ATOM: str_append(dest, imap_arg_as_astring(arg)); break; - case IMAP_ARG_STRING: + case IMAP_ARG_STRING: { + const char *strarg = imap_arg_as_astring(arg); str_append_c(dest, '"'); - str_append(dest, str_escape(imap_arg_as_astring(arg))); + str_append_escaped(dest, strarg, strlen(strarg)); str_append_c(dest, '"'); break; + } case IMAP_ARG_LITERAL: { const char *strarg = imap_arg_as_astring(arg); str_printfa(dest, "{%"PRIuSIZE_T"}\r\n", diff --git a/src/lib-imap/test-imap-util.c b/src/lib-imap/test-imap-util.c index 215eb21380..90f59a1c80 100644 --- a/src/lib-imap/test-imap-util.c +++ b/src/lib-imap/test-imap-util.c @@ -1,7 +1,9 @@ /* Copyright (c) 2009-2018 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "str.h" #include "mail-types.h" +#include "imap-arg.h" #include "imap-util.h" #include "test-common.h" @@ -21,10 +23,56 @@ static void test_imap_parse_system_flag(void) test_end(); } +static void test_imap_write_arg(void) +{ + ARRAY_TYPE(imap_arg_list) list_root, list_sub; + struct imap_arg *arg; + + t_array_init(&list_sub, 2); + arg = array_append_space(&list_sub); + arg->type = IMAP_ARG_ATOM; + arg->_data.str = "foo"; + arg = array_append_space(&list_sub); + arg->type = IMAP_ARG_EOL; + + t_array_init(&list_root, 2); + arg = array_append_space(&list_root); + arg->type = IMAP_ARG_LIST; + arg->_data.list = list_sub; + arg = array_append_space(&list_root); + arg->type = IMAP_ARG_STRING; + arg->_data.str = "bar"; + arg = array_append_space(&list_root); + arg->type = IMAP_ARG_EOL; + + const struct { + struct imap_arg input; + const char *output; + } tests[] = { + { { .type = IMAP_ARG_NIL }, "NIL" }, + { { .type = IMAP_ARG_ATOM, ._data.str = "atom" }, "atom" }, + { { .type = IMAP_ARG_STRING, ._data.str = "s\\t\"ring" }, "\"s\\\\t\\\"ring\"" }, + { { .type = IMAP_ARG_LITERAL, ._data.str = "l\\i\"t\r\neral" }, "{11}\r\nl\\i\"t\r\neral" }, + { { .type = IMAP_ARG_LITERAL_SIZE, ._data.literal_size = 12345678 }, "<12345678 byte literal>" }, + { { .type = IMAP_ARG_LITERAL_SIZE_NONSYNC, ._data.literal_size = 12345678 }, "<12345678 byte literal>" }, + { { .type = IMAP_ARG_LIST, ._data.list = list_root }, "((foo) \"bar\")" }, + }; + string_t *str = t_str_new(100); + + test_begin("imap_write_arg"); + for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) { + str_truncate(str, 0); + imap_write_arg(str, &tests[i].input); + test_assert_idx(strcmp(str_c(str), tests[i].output) == 0, i); + } + test_end(); +} + int main(void) { static void (*const test_functions[])(void) = { test_imap_parse_system_flag, + test_imap_write_arg, NULL }; return test_run(test_functions);