dovecot-2.2: lib-mail: rfc822_parse_content_param() was unescapi...

dovecot at dovecot.org dovecot at dovecot.org
Mon Nov 30 11:15:58 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/9eab653f5b94
changeset: 19435:9eab653f5b94
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Nov 30 13:14:29 2015 +0200
description:
lib-mail: rfc822_parse_content_param() was unescaping already unescaped parameters
This caused all Content-* parameter parsing to be unescaped once too many
times, resulting in somewhat broken BODY and BODYSTRUCTURE replies if any
<\> characters were used. Also MIME boundaries were parsed in case <\> was
used in them, but this probably didn't practically happen.

diffstat:

 src/lib-mail/Makefile.am          |   7 +++-
 src/lib-mail/rfc822-parser.c      |   1 -
 src/lib-mail/test-rfc822-parser.c |  74 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 80 insertions(+), 2 deletions(-)

diffs (113 lines):

diff -r 9a15b989cc41 -r 9eab653f5b94 src/lib-mail/Makefile.am
--- a/src/lib-mail/Makefile.am	Mon Nov 30 12:22:22 2015 +0200
+++ b/src/lib-mail/Makefile.am	Mon Nov 30 13:14:29 2015 +0200
@@ -95,7 +95,8 @@
 	test-ostream-dot \
 	test-qp-decoder \
 	test-quoted-printable \
-	test-rfc2231-parser
+	test-rfc2231-parser \
+	test-rfc822-parser
 
 noinst_PROGRAMS = $(test_programs)
 
@@ -196,6 +197,10 @@
 test_rfc2231_parser_LDADD = rfc2231-parser.lo rfc822-parser.lo $(test_libs)
 test_rfc2231_parser_DEPENDENCIES = $(test_deps)
 
+test_rfc822_parser_SOURCES = test-rfc822-parser.c
+test_rfc822_parser_LDADD = rfc822-parser.lo $(test_libs)
+test_rfc822_parser_DEPENDENCIES = $(test_deps)
+
 check: check-am check-test
 check-test: all-am
 	for bin in $(test_programs); do \
diff -r 9a15b989cc41 -r 9eab653f5b94 src/lib-mail/rfc822-parser.c
--- a/src/lib-mail/rfc822-parser.c	Mon Nov 30 12:22:22 2015 +0200
+++ b/src/lib-mail/rfc822-parser.c	Mon Nov 30 13:14:29 2015 +0200
@@ -409,7 +409,6 @@
 		/* broken / no value */
 	} else if (*ctx->data == '"') {
 		ret = rfc822_parse_quoted_string(ctx, tmp);
-		(void)str_unescape(str_c_modifiable(tmp) + value_pos);
 	} else if (ctx->data != ctx->end && *ctx->data == '=') {
 		/* workaround for broken input:
 		   name==?utf-8?b?...?= */
diff -r 9a15b989cc41 -r 9eab653f5b94 src/lib-mail/test-rfc822-parser.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-mail/test-rfc822-parser.c	Mon Nov 30 13:14:29 2015 +0200
@@ -0,0 +1,74 @@
+/* Copyright (c) 2015 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "str.h"
+#include "rfc822-parser.h"
+#include "test-common.h"
+
+static void test_rfc822_parse_quoted_string(void)
+{
+	const struct {
+		const char *input, *output;
+		int ret;
+	} tests[] = {
+		{ "\"", "", -1 },
+		{ "\"\"", "", 0 },
+		{ "\"foo\"", "foo", 0 },
+		{ "\"\"foo", "", 1 },
+		{ "\"\"\"", "", 1 },
+		{ "\"\\\"\"", "\"", 0 },
+		{ "\"\\\\\"", "\\", 0 },
+		{ "\"\\\\foo\\\\foo\\\\\"", "\\foo\\foo\\", 0 }
+	};
+	struct rfc822_parser_context parser;
+	string_t *str = t_str_new(64);
+	unsigned int i = 0;
+
+	test_begin("rfc822 parse quoted string");
+	for (i = 0; i < N_ELEMENTS(tests); i++) {
+		rfc822_parser_init(&parser, (const void *)tests[i].input,
+				   strlen(tests[i].input), NULL);
+		test_assert_idx(rfc822_parse_quoted_string(&parser, str) == tests[i].ret, i);
+		test_assert_idx(tests[i].ret < 0 ||
+				strcmp(tests[i].output, str_c(str)) == 0, i);
+		str_truncate(str, 0);
+	}
+	test_end();
+}
+
+static void test_rfc822_parse_content_param(void)
+{
+	const char *input =
+		"; key1=value1#$!%&'*+-.^_`{|}~"
+		"; key2=\" \\\"(),/:;<=>?@[\\\\]\"";
+	const struct {
+		const char *key, *value;
+	} output[] = {
+		{ "key1", "value1#$!%&'*+-.^_`{|}~" },
+		{ "key2", " \"(),/:;<=>?@[\\]" }
+	};
+	struct rfc822_parser_context parser;
+	const char *key, *value;
+	unsigned int i = 0;
+	int ret;
+
+	test_begin("rfc822 parse content param");
+	rfc822_parser_init(&parser, (const void *)input, strlen(input), NULL);
+	while ((ret = rfc822_parse_content_param(&parser, &key, &value)) > 0) {
+		test_assert_idx(strcmp(output[i].key, key) == 0, i);
+		test_assert_idx(strcmp(output[i].value, value) == 0, i);
+		i++;
+	}
+	test_assert(ret == 0);
+	test_end();
+}
+
+int main(void)
+{
+	static void (*test_functions[])(void) = {
+		test_rfc822_parse_quoted_string,
+		test_rfc822_parse_content_param,
+		NULL
+	};
+	return test_run(test_functions);
+}


More information about the dovecot-cvs mailing list