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