]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-imap: added imap_append_nstring_nolf(), which skips CRs and LFs.
authorSergey Kitov <sergey.kitov@open-xchange.com>
Wed, 14 Jun 2017 07:41:04 +0000 (10:41 +0300)
committerGitLab <gitlab@git.dovecot.net>
Thu, 15 Jun 2017 08:21:42 +0000 (11:21 +0300)
src/lib-imap/imap-quote.c
src/lib-imap/imap-quote.h
src/lib-imap/test-imap-quote.c

index f4ff853b90826db00f76cfa3c5b009089d51dad2..3e751245d3173444d1b123d1a520152f98da1ac3 100644 (file)
@@ -90,6 +90,33 @@ void imap_append_nstring(string_t *dest, const char *src)
        imap_append_quoted(dest, src);
 }
 
+void imap_append_nstring_nolf(string_t *dest, const char *src)
+{
+       string_t *src_nolf;
+       size_t src_len;
+       if (src == NULL || strpbrk(src, "\r\n") == NULL)
+               imap_append_nstring(dest, src);
+       else {
+               T_BEGIN {
+                       src_len = strlen(src);
+                       src_nolf = t_str_new(src_len + 1);
+                       for (size_t i = 0; i < src_len; ++i) {
+                               if (src[i] != '\r' && src[i] != '\n') {
+                                       str_append_c(src_nolf, src[i]);
+                               } else if (src[i+1] != ' ' &&
+                                          src[i+1] != '\t' &&
+                                          src[i+1] != '\r' &&
+                                          src[i+1] != '\n' &&
+                                          src[i+1] != '\0') {
+                                       /* ensure whitespace between lines if new line doesn't start with whitespace */
+                                       str_append_c(src_nolf, ' ');
+                               }
+                       }
+                       imap_append_nstring(dest, str_c(src_nolf));
+               } T_END;
+       }
+}
+
 void imap_append_quoted(string_t *dest, const char *src)
 {
        str_append_c(dest, '"');
index 65fb1b3b3aa21baace79430396e24fccbff5ae43..a397ec39bc372e1ac9b0803ab39178579da4aef9 100644 (file)
@@ -7,6 +7,8 @@ void imap_append_string(string_t *dest, const char *src);
 void imap_append_astring(string_t *dest, const char *src);
 /* Append NIL, "quoted" or literal. */
 void imap_append_nstring(string_t *dest, const char *src);
+/* Append NIL, "quoted" or literal, CRs and LFs skipped. */
+void imap_append_nstring_nolf(string_t *dest, const char *src);
 /* Append "quoted". If src has 8bit chars, skip over them. */
 void imap_append_quoted(string_t *dest, const char *src);
 
index 65adfea78d822d495093dbd2b367aac41885e720..9377e0142733376220d706cec4b3ecde6a8e8952 100644 (file)
@@ -112,12 +112,51 @@ static void test_imap_append_nstring(void)
        test_end();
 }
 
+static void test_imap_append_nstring_nolf(void)
+{
+       static const struct {
+               const char *input, *output;
+       } tests[] = {
+               { "", "\"\"" },
+               { NULL, "NIL" },
+               { "NIL", "\"NIL\"" },
+               { "ni", "\"ni\"" },
+               { "\"NIL\n foo", "\"\\\"NIL foo\"" },
+               { "\"America N.\", \"America S.\", \"Africa\"", "{36}\r\n\"America N.\", \"America S.\", \"Africa\"" },
+               { "foo\nbar", "\"foo bar\"" },
+               { "foo\r\nbar", "\"foo bar\"" },
+               { "foo\rbar", "\"foo bar\"" },
+               { "foo\n  bar", "\"foo  bar\"" },
+               { "foo\r\n  bar", "\"foo  bar\"" },
+               { "foo\r  bar", "\"foo  bar\"" },
+               { "foo\n\tbar", "\"foo\tbar\"" },
+               { "foo\r\n\tbar", "\"foo\tbar\"" },
+               { "foo\r\tbar", "\"foo\tbar\"" },
+               { "foo\n bar", "\"foo bar\"" },
+               { "foo\r\n bar", "\"foo bar\"" },
+               { "foo\r bar", "\"foo bar\"" },
+               { "\nfoo\r bar\r\n", "\" foo bar\"" }
+       };
+       string_t *str = t_str_new(128);
+       unsigned int i;
+
+       test_begin("test_imap_append_nstring_nolf()");
+
+       for (i = 0; i < N_ELEMENTS(tests); i++) {
+               str_truncate(str, 0);
+               imap_append_nstring_nolf(str, tests[i].input);
+               test_assert_idx(strcmp(tests[i].output, str_c(str)) == 0, i);
+       }
+       test_end();
+}
+
 int main(void)
 {
        static void (*const test_functions[])(void) = {
                test_imap_append_string_for_humans,
                test_imap_append_astring,
                test_imap_append_nstring,
+               test_imap_append_nstring_nolf,
                NULL
        };
        return test_run(test_functions);