dovecot-2.0: Added str_append_tabunescaped(). str_tabescape*() n...

dovecot at dovecot.org dovecot at dovecot.org
Tue Jun 16 20:49:23 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/5a6fe52a0cfc
changeset: 9484:5a6fe52a0cfc
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Jun 16 13:49:18 2009 -0400
description:
Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.

diffstat:

6 files changed, 127 insertions(+), 3 deletions(-)
src/lib/Makefile.am      |    1 
src/lib/strescape.c      |   52 +++++++++++++++++++++++++++++++--
src/lib/strescape.h      |    3 +
src/lib/test-lib.c       |    1 
src/lib/test-lib.h       |    1 
src/lib/test-strescape.c |   72 ++++++++++++++++++++++++++++++++++++++++++++++

diffs (205 lines):

diff -r 464116e1d0ae -r 5a6fe52a0cfc src/lib/Makefile.am
--- a/src/lib/Makefile.am	Tue Jun 16 13:39:40 2009 -0400
+++ b/src/lib/Makefile.am	Tue Jun 16 13:49:18 2009 -0400
@@ -221,6 +221,7 @@ test_lib_SOURCES = \
 	test-primes.c \
 	test-priorityq.c \
 	test-seq-range-array.c \
+	test-strescape.c \
 	test-str-find.c \
 	test-str-sanitize.c \
 	test-utc-mktime.c
diff -r 464116e1d0ae -r 5a6fe52a0cfc src/lib/strescape.c
--- a/src/lib/strescape.c	Tue Jun 16 13:39:40 2009 -0400
+++ b/src/lib/strescape.c	Tue Jun 16 13:49:18 2009 -0400
@@ -65,8 +65,11 @@ char *str_unescape(char *str)
 	}
 
 	for (dest = str; *str != '\0'; str++) {
-		if (*str == '\\' && str[1] != '\0')
+		if (*str == '\\') {
 			str++;
+			if (*str == '\0')
+				break;
+		}
 
 		*dest++ = *str;
 	}
@@ -87,6 +90,10 @@ void str_tabescape_write(string_t *dest,
 			str_append_c(dest, '\001');
 			str_append_c(dest, 't');
 			break;
+		case '\r':
+			str_append_c(dest, '\001');
+			str_append_c(dest, 'r');
+			break;
 		case '\n':
 			str_append_c(dest, '\001');
 			str_append_c(dest, 'n');
@@ -104,7 +111,7 @@ const char *str_tabescape(const char *st
 	const char *p;
 
 	for (p = str; *p != '\0'; p++) {
-		if (*p <= '\n') {
+		if (*p <= '\r') {
 			tmp = t_str_new(128);
 			str_append_n(tmp, str, p-str);
 			str_tabescape_write(tmp, p);
@@ -113,3 +120,44 @@ const char *str_tabescape(const char *st
 	}
 	return str;
 }
+
+void str_append_tabunescaped(string_t *dest, const void *src, size_t src_size)
+{
+	const unsigned char *src_c = src;
+	size_t start = 0, i = 0;
+
+	while (i < src_size) {
+		start = i;
+		for (; i < src_size; i++) {
+			if (src_c[i] == '\001')
+				break;
+		}
+
+		str_append_n(dest, src_c + start, i-start);
+
+		if (i < src_size) {
+			i++;
+			if (i < src_size) {
+				switch (src_c[i]) {
+				case '1':
+					str_append_c(dest, '\001');
+					break;
+				case 't':
+					str_append_c(dest, '\t');
+					break;
+				case 'r':
+					str_append_c(dest, '\r');
+					break;
+				case 'n':
+					str_append_c(dest, '\n');
+					break;
+				default:
+					str_append_c(dest, src_c[i]);
+					break;
+				}
+				i++;
+			}
+		}
+		start = i;
+	}
+}
diff -r 464116e1d0ae -r 5a6fe52a0cfc src/lib/strescape.h
--- a/src/lib/strescape.h	Tue Jun 16 13:39:40 2009 -0400
+++ b/src/lib/strescape.h	Tue Jun 16 13:49:18 2009 -0400
@@ -12,9 +12,10 @@ void str_append_unescaped(string_t *dest
 /* remove all '\' characters */
 char *str_unescape(char *str);
 
-/* For Dovecot's internal protocols: Escape \001, \t and \n characters
+/* For Dovecot's internal protocols: Escape \001, \t, \r and \n characters
    using \001. */
 const char *str_tabescape(const char *str);
 void str_tabescape_write(string_t *dest, const char *src);
+void str_append_tabunescaped(string_t *dest, const void *src, size_t src_size);
 
 #endif
diff -r 464116e1d0ae -r 5a6fe52a0cfc src/lib/test-lib.c
--- a/src/lib/test-lib.c	Tue Jun 16 13:39:40 2009 -0400
+++ b/src/lib/test-lib.c	Tue Jun 16 13:49:18 2009 -0400
@@ -16,6 +16,7 @@ int main(void)
 		test_primes,
 		test_priorityq,
 		test_seq_range_array,
+		test_strescape,
 		test_str_find,
 		test_str_sanitize,
 		test_utc_mktime,
diff -r 464116e1d0ae -r 5a6fe52a0cfc src/lib/test-lib.h
--- a/src/lib/test-lib.h	Tue Jun 16 13:39:40 2009 -0400
+++ b/src/lib/test-lib.h	Tue Jun 16 13:49:18 2009 -0400
@@ -15,6 +15,7 @@ void test_primes(void);
 void test_primes(void);
 void test_priorityq(void);
 void test_seq_range_array(void);
+void test_strescape(void);
 void test_str_find(void);
 void test_str_sanitize(void);
 void test_utc_mktime(void);
diff -r 464116e1d0ae -r 5a6fe52a0cfc src/lib/test-strescape.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/test-strescape.c	Tue Jun 16 13:49:18 2009 -0400
@@ -0,0 +1,72 @@
+/* Copyright (c) 2009 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "str.h"
+#include "strescape.h"
+
+struct strinput {
+	const char *input;
+	const char *output;
+};
+
+void test_strescape(void)
+{
+	static struct strinput unesc[] = {
+		{ "foo", "foo" },
+		{ "\\\\\\\\\\\"\\\"\\\'\\\'", "\\\\\"\"\'\'" },
+		{ "\\a\\n\\r\\", "anr" }
+	};
+	static struct strinput tabesc[] = {
+		{ "foo", "foo" },
+		{ "\001", "\0011" },
+		{ "\t", "\001t" },
+		{ "\r", "\001r" },
+		{ "\n", "\001n" },
+		{ "\001\001\t\t\r\r\n\n", "\0011\0011\001t\001t\001r\001r\001n\001n" }
+	};
+	unsigned char buf[1 << CHAR_BIT];
+	const char *escaped;
+	string_t *str;
+	unsigned int i;
+
+	test_begin("str_escape");
+	for (i = 1; i < sizeof(buf); i++)
+		buf[i-1] = i;
+	buf[i-1] = '\0';
+
+	escaped = str_escape((char *)buf);
+	test_assert(strlen(escaped) == (1 << CHAR_BIT) - 1 + 3);
+	test_assert(escaped['\"'-1] == '\\'); /* 34 */
+	test_assert(escaped['\"'] == '\"');
+	test_assert(escaped['\''+1-1] == '\\'); /* 39 */
+	test_assert(escaped['\''+1] == '\'');
+	test_assert(escaped['\\'+2-1] == '\\'); /* 92 */
+	test_assert(escaped['\\'+2] == '\\');
+	test_assert(strcmp(str_escape("\\\\\"\"\'\'"),
+			   "\\\\\\\\\\\"\\\"\\\'\\\'") == 0);
+	test_end();
+
+	str = t_str_new(256);
+	test_begin("str_unescape");
+	for (i = 0; i < N_ELEMENTS(unesc); i++) {
+		test_assert(strcmp(str_unescape(t_strdup_noconst(unesc[i].input)),
+				   unesc[i].output) == 0);
+		str_truncate(str, 0);
+		str_append_unescaped(str, unesc[i].input, strlen(unesc[i].input));
+		test_assert(strcmp(str_c(str), unesc[i].output) == 0);
+	}
+	test_end();
+
+	test_begin("str_tabescape");
+	for (i = 0; i < N_ELEMENTS(tabesc); i++) {
+		test_assert(strcmp(str_tabescape(tabesc[i].input),
+				   tabesc[i].output) == 0);
+		str_truncate(str, 0);
+		str_append_tabunescaped(str, tabesc[i].output, strlen(tabesc[i].output));
+		test_assert(strcmp(str_c(str), tabesc[i].input) == 0);
+	}
+	str_truncate(str, 0);
+	str_append_tabunescaped(str, "\0012\001l\001", strlen("\0012\001l\001"));
+	test_assert(strcmp(str_c(str), "2l") == 0);
+	test_end();
+}


More information about the dovecot-cvs mailing list