]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-imap: imap_write_arg() - minor optimization to IMAP_ARG_STRING
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 24 Oct 2019 08:43:58 +0000 (11:43 +0300)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Thu, 23 Jan 2020 10:48:22 +0000 (10:48 +0000)
Avoid unnecessarily using data stack.

Also add unit tests to imap_write_arg().

src/lib-imap/imap-util.c
src/lib-imap/test-imap-util.c

index 34ebe5d203af2514ade5ff495826aaa4895206bf..b6d4258131eec5a8d928b379202941698e0590f5 100644 (file)
@@ -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",
index 215eb21380f2363c6ddcfb8955f3955a9945cdb7..90f59a1c8077bb30e11c954a0ca04783ad908808 100644 (file)
@@ -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);