changeset 22236:d0ce40449889

lib-imap: added imap_append_nstring_nolf(), which skips CRs and LFs.
author Sergey Kitov <sergey.kitov@open-xchange.com>
date Wed, 14 Jun 2017 10:41:04 +0300
parents cdb9410662d1
children c8b7596cef7f
files src/lib-imap/imap-quote.c src/lib-imap/imap-quote.h src/lib-imap/test-imap-quote.c
diffstat 3 files changed, 68 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-imap/imap-quote.c	Tue Jun 13 10:05:23 2017 +0300
+++ b/src/lib-imap/imap-quote.c	Wed Jun 14 10:41:04 2017 +0300
@@ -90,6 +90,33 @@
 	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, '"');
--- a/src/lib-imap/imap-quote.h	Tue Jun 13 10:05:23 2017 +0300
+++ b/src/lib-imap/imap-quote.h	Wed Jun 14 10:41:04 2017 +0300
@@ -7,6 +7,8 @@
 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);
 
--- a/src/lib-imap/test-imap-quote.c	Tue Jun 13 10:05:23 2017 +0300
+++ b/src/lib-imap/test-imap-quote.c	Wed Jun 14 10:41:04 2017 +0300
@@ -112,12 +112,51 @@
 	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 (*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);