dovecot-2.2: lib-imap: imap_append_string_for_humans() returned ...
dovecot at dovecot.org
dovecot at dovecot.org
Wed May 29 16:40:55 EEST 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/714320c3cfa6
changeset: 16417:714320c3cfa6
user: Timo Sirainen <tss at iki.fi>
date: Wed May 29 16:40:50 2013 +0300
description:
lib-imap: imap_append_string_for_humans() returned broken output for whitespace-only input.
This returned broken IMAP ENVELOPEs, especially for subjects that contained
only whitespace. Since the broken output returned a huge literal, it
basically caused the IMAP client to hang.
diffstat:
src/lib-imap/Makefile.am | 5 ++++
src/lib-imap/imap-quote.c | 17 +++++++++++---
src/lib-imap/test-imap-quote.c | 47 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 65 insertions(+), 4 deletions(-)
diffs (127 lines):
diff -r f294d40a8978 -r 714320c3cfa6 src/lib-imap/Makefile.am
--- a/src/lib-imap/Makefile.am Wed May 29 12:44:15 2013 +0300
+++ b/src/lib-imap/Makefile.am Wed May 29 16:40:50 2013 +0300
@@ -44,6 +44,7 @@
test-imap-bodystructure \
test-imap-match \
test-imap-parser \
+ test-imap-quote \
test-imap-url \
test-imap-utf7 \
test-imap-util
@@ -68,6 +69,10 @@
test_imap_parser_LDADD = imap-parser.lo imap-arg.lo $(test_libs)
test_imap_parser_DEPENDENCIES = $(test_deps)
+test_imap_quote_SOURCES = test-imap-quote.c
+test_imap_quote_LDADD = imap-quote.lo $(test_libs)
+test_imap_quote_DEPENDENCIES = $(test_deps)
+
test_imap_url_SOURCES = test-imap-url.c
test_imap_url_LDADD = imap-url.lo $(test_libs)
test_imap_url_DEPENDENCIES = $(test_deps)
diff -r f294d40a8978 -r 714320c3cfa6 src/lib-imap/imap-quote.c
--- a/src/lib-imap/imap-quote.c Wed May 29 12:44:15 2013 +0300
+++ b/src/lib-imap/imap-quote.c Wed May 29 16:40:50 2013 +0300
@@ -119,7 +119,7 @@
const unsigned char *src, size_t size)
{
size_t i, pos, remove_count = 0;
- bool last_lwsp = TRUE, modify = FALSE;
+ bool whitespace_prefix = TRUE, last_lwsp = TRUE, modify = FALSE;
/* first check if there is anything to change */
for (i = 0; i < size; i++) {
@@ -155,8 +155,10 @@
last_lwsp = FALSE;
break;
}
+ if (!last_lwsp)
+ whitespace_prefix = FALSE;
}
- if (last_lwsp && i > 0) {
+ if (last_lwsp && i > 0 && !whitespace_prefix) {
modify = TRUE;
remove_count++;
}
@@ -168,11 +170,16 @@
str_append_c(dest, '"');
return;
}
+ if (size == remove_count) {
+ /* contained only whitespace */
+ str_append(dest, "\"\"");
+ return;
+ }
str_printfa(dest, "{%"PRIuSIZE_T"}\r\n", size - remove_count);
pos = str_len(dest);
- last_lwsp = TRUE;
+ last_lwsp = TRUE; whitespace_prefix = TRUE;
for (i = 0; i < size; i++) {
switch (src[i]) {
case 0:
@@ -193,8 +200,10 @@
str_append_c(dest, src[i]);
break;
}
+ if (!last_lwsp)
+ whitespace_prefix = FALSE;
}
- if (last_lwsp)
+ if (last_lwsp && i > 0 && !whitespace_prefix)
str_truncate(dest, str_len(dest)-1);
i_assert(str_len(dest) - pos == size - remove_count);
}
diff -r f294d40a8978 -r 714320c3cfa6 src/lib-imap/test-imap-quote.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-imap/test-imap-quote.c Wed May 29 16:40:50 2013 +0300
@@ -0,0 +1,47 @@
+/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "str.h"
+#include "imap-quote.h"
+#include "test-common.h"
+
+static void test_imap_append_string_for_humans(void)
+{
+ static struct {
+ const char *input, *output;
+ } tests[] = {
+ { "", "\"\"" },
+ { " ", "\"\"" },
+ { " ", "\"\"" },
+ { "\t", "\"\"" },
+ { " \t", "\"\"" },
+ { " \t ", "\"\"" },
+ { " foo", "{3}\r\nfoo" },
+ { "\tfoo", "{3}\r\nfoo" },
+ { "\t \tfoo", "{3}\r\nfoo" },
+ { " foo ", "{3}\r\nfoo" },
+ { " foo ", "{3}\r\nfoo" },
+ { " foo \t \t", "{3}\r\nfoo" }
+ };
+ string_t *str = t_str_new(128);
+ unsigned int i;
+
+ test_begin("imap_append_string_for_humans()");
+
+ for (i = 0; i < N_ELEMENTS(tests); i++) {
+ str_truncate(str, 0);
+ imap_append_string_for_humans(str, (const void *)tests[i].input,
+ strlen(tests[i].input));
+ test_assert(strcmp(tests[i].output, str_c(str)) == 0);
+ }
+ test_end();
+}
+
+int main(void)
+{
+ static void (*test_functions[])(void) = {
+ test_imap_append_string_for_humans,
+ NULL
+ };
+ return test_run(test_functions);
+}
More information about the dovecot-cvs
mailing list