dovecot-2.0-sslstream: lib-dict: Added dict_[un]escape_string().
dovecot at dovecot.org
dovecot at dovecot.org
Sat Feb 13 03:00:32 EET 2010
details: http://hg.dovecot.org/dovecot-2.0-sslstream/rev/2cfe01556d6c
changeset: 10638:2cfe01556d6c
user: Timo Sirainen <tss at iki.fi>
date: Fri Feb 05 19:23:42 2010 +0200
description:
lib-dict: Added dict_[un]escape_string().
diffstat:
4 files changed, 138 insertions(+)
src/lib-dict/Makefile.am | 20 +++++++++++++
src/lib-dict/dict.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++
src/lib-dict/dict.h | 5 +++
src/lib-dict/test-dict.c | 43 ++++++++++++++++++++++++++++
diffs (178 lines):
diff -r 7ebf82401e7a -r 2cfe01556d6c src/lib-dict/Makefile.am
--- a/src/lib-dict/Makefile.am Fri Feb 05 18:04:16 2010 +0200
+++ b/src/lib-dict/Makefile.am Fri Feb 05 19:23:42 2010 +0200
@@ -5,6 +5,7 @@ dict_drivers = @dict_drivers@
AM_CPPFLAGS = \
-I$(top_srcdir)/src/lib \
+ -I$(top_srcdir)/src/lib-test \
-I$(top_srcdir)/src/lib-sql \
-I$(top_srcdir)/src/lib-settings \
$(SQL_CFLAGS)
@@ -72,3 +73,22 @@ DISTFILES = $(DIST_COMMON) $(base_source
distclean-generic:
rm -f Makefile dict-drivers-register.c
+
+test_programs = \
+ test-dict
+
+noinst_PROGRAMS = $(test_programs)
+
+test_libs = \
+ ../lib-test/libtest.la \
+ ../lib/liblib.la
+
+test_dict_SOURCES = test-dict.c
+test_dict_LDADD = dict.lo $(test_libs)
+test_dict_DEPENDENCIES = dict.lo $(test_libs)
+
+check: check-am check-test
+check-test: all-am
+ for bin in $(test_programs); do \
+ if ! ./$$bin; then exit 1; fi; \
+ done
diff -r 7ebf82401e7a -r 2cfe01556d6c src/lib-dict/dict.c
--- a/src/lib-dict/dict.c Fri Feb 05 18:04:16 2010 +0200
+++ b/src/lib-dict/dict.c Fri Feb 05 19:23:42 2010 +0200
@@ -2,6 +2,7 @@
#include "lib.h"
#include "array.h"
+#include "str.h"
#include "dict-sql.h"
#include "dict-private.h"
@@ -194,3 +195,72 @@ void dict_atomic_inc(struct dict_transac
ctx->changed = TRUE;
}
}
+
+const char *dict_escape_string(const char *str)
+{
+ const char *p;
+ string_t *ret;
+
+ /* see if we need to escape it */
+ for (p = str; *p != '\0'; p++) {
+ if (*p == '/' || *p == '\\')
+ break;
+ }
+
+ if (*p == '\0')
+ return str;
+
+ /* escape */
+ ret = t_str_new((size_t) (p - str) + 128);
+ str_append_n(ret, str, (size_t) (p - str));
+
+ for (; *p != '\0'; p++) {
+ switch (*p) {
+ case '/':
+ str_append_c(ret, '\\');
+ str_append_c(ret, '|');
+ break;
+ case '\\':
+ str_append_c(ret, '\\');
+ str_append_c(ret, '\\');
+ break;
+ default:
+ str_append_c(ret, *p);
+ break;
+ }
+ }
+ return str_c(ret);
+}
+
+const char *dict_unescape_string(const char *str)
+{
+ const char *p;
+ string_t *ret;
+
+ /* see if we need to unescape it */
+ for (p = str; *p != '\0'; p++) {
+ if (*p == '\\')
+ break;
+ }
+
+ if (*p == '\0')
+ return str;
+
+ /* unescape */
+ ret = t_str_new((size_t) (p - str) + strlen(p) + 1);
+ str_append_n(ret, str, (size_t) (p - str));
+
+ for (; *p != '\0'; p++) {
+ if (*p != '\\')
+ str_append_c(ret, *p);
+ else {
+ if (*++p == '|')
+ str_append_c(ret, '/');
+ else if (*p == '\0')
+ break;
+ else
+ str_append_c(ret, *p);
+ }
+ }
+ return str_c(ret);
+}
diff -r 7ebf82401e7a -r 2cfe01556d6c src/lib-dict/dict.h
--- a/src/lib-dict/dict.h Fri Feb 05 18:04:16 2010 +0200
+++ b/src/lib-dict/dict.h Fri Feb 05 19:23:42 2010 +0200
@@ -81,4 +81,9 @@ void dict_atomic_inc(struct dict_transac
void dict_atomic_inc(struct dict_transaction_context *ctx,
const char *key, long long diff);
+/* Escape/unescape '/' characters in a string, so that it can be safely added
+ into path components in dict keys. */
+const char *dict_escape_string(const char *str);
+const char *dict_unescape_string(const char *str);
+
#endif
diff -r 7ebf82401e7a -r 2cfe01556d6c src/lib-dict/test-dict.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-dict/test-dict.c Fri Feb 05 19:23:42 2010 +0200
@@ -0,0 +1,43 @@
+/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "dict-private.h"
+#include "test-common.h"
+
+struct dict dict_driver_client;
+struct dict dict_driver_file;
+
+static void test_dict_escape(void)
+{
+ static const char *input[] = {
+ "", "",
+ "foo", "foo",
+ "foo\\", "foo\\\\",
+ "foo\\bar", "foo\\\\bar",
+ "\\bar", "\\\\bar",
+ "foo/", "foo\\|",
+ "foo/bar", "foo\\|bar",
+ "/bar", "\\|bar",
+ "////", "\\|\\|\\|\\|",
+ "/", "\\|"
+ };
+ unsigned int i;
+
+ test_begin("dict escape");
+ for (i = 0; i < N_ELEMENTS(input); i += 2) {
+ test_assert(strcmp(dict_escape_string(input[i]), input[i+1]) == 0);
+ test_assert(strcmp(dict_unescape_string(input[i+1]), input[i]) == 0);
+ }
+ test_assert(strcmp(dict_unescape_string("x\\"), "x") == 0);
+ test_assert(strcmp(dict_unescape_string("\\"), "") == 0);
+ test_end();
+}
+
+int main(void)
+{
+ static void (*test_functions[])(void) = {
+ test_dict_escape,
+ NULL
+ };
+ return test_run(test_functions);
+}
More information about the dovecot-cvs
mailing list