changeset 22258:a2e6b623fa38

lib-imap: imap_append_nstring_nolf() - fix crash with datastack_pool strings T_BEGIN .. T_END is not used, when string_t is allocated from datastack pool, unit test updated to verify the fix.
author Sergey Kitov <sergey.kitov@open-xchange.com>
date Tue, 20 Jun 2017 12:11:37 +0300
parents 024acbef16ea
children e6bb15e22709
files src/lib-imap/imap-quote.c src/lib-imap/test-imap-quote.c
diffstat 2 files changed, 37 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-imap/imap-quote.c	Mon Jun 19 23:43:17 2017 +0300
+++ b/src/lib-imap/imap-quote.c	Tue Jun 20 12:11:37 2017 +0300
@@ -90,31 +90,36 @@
 	imap_append_quoted(dest, src);
 }
 
+static void remove_newlines_and_append(string_t *dest, const char *src)
+{
+	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)
 {
-	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;
-	}
+	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)
--- a/src/lib-imap/test-imap-quote.c	Mon Jun 19 23:43:17 2017 +0300
+++ b/src/lib-imap/test-imap-quote.c	Tue Jun 20 12:11:37 2017 +0300
@@ -137,16 +137,24 @@
 		{ "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();
 }