]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-imap: imap_append_nstring_nolf() - fix crash with datastack_pool strings
authorSergey Kitov <sergey.kitov@open-xchange.com>
Tue, 20 Jun 2017 09:11:37 +0000 (12:11 +0300)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Tue, 20 Jun 2017 10:57:56 +0000 (13:57 +0300)
T_BEGIN .. T_END is not used, when string_t is allocated from
datastack pool, unit test updated to verify the fix.

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

index 3e751245d3173444d1b123d1a520152f98da1ac3..260176899cd74390002c805396f2b7121be1c4c5 100644 (file)
@@ -90,31 +90,36 @@ 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)
+static void remove_newlines_and_append(string_t *dest, const char *src)
 {
-       string_t *src_nolf;
        size_t src_len;
+       string_t *src_nolf;
+       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));
+}
+
+void imap_append_nstring_nolf(string_t *dest, const char *src)
+{
        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;
-       }
+       else if (buffer_get_pool(dest)->datastack_pool)
+               remove_newlines_and_append(dest, src);
+       else T_BEGIN {
+               remove_newlines_and_append(dest, src);
+       } T_END;
 }
 
 void imap_append_quoted(string_t *dest, const char *src)
index 9b94dd638de46eb84064f81effd00af55bdbecc3..03d61eacc78a634f9b753aad1f649976c0504ec9 100644 (file)
@@ -137,16 +137,24 @@ static void test_imap_append_nstring_nolf(void)
                { "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++) {
+       for (i = 0; i < N_ELEMENTS(tests); i++) T_BEGIN {
+               string_t *str = t_str_new(1);
+               string_t *str2 = str_new(default_pool, 1);
+
                str_truncate(str, 0);
                imap_append_nstring_nolf(str, tests[i].input);
                test_assert_idx(strcmp(tests[i].output, str_c(str)) == 0, i);
-       }
+
+               str_truncate(str2, 0);
+               imap_append_nstring_nolf(str2, tests[i].input);
+               test_assert_idx(strcmp(tests[i].output, str_c(str2)) == 0, i);
+
+               str_free(&str2);
+       } T_END;
        test_end();
 }