dovecot-2.2: lib-mail: Fixed modifying headers with i_stream_hea...

dovecot at dovecot.org dovecot at dovecot.org
Tue Apr 28 12:22:30 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/aa8786771490
changeset: 18488:aa8786771490
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Apr 28 14:20:39 2015 +0200
description:
lib-mail: Fixed modifying headers with i_stream_header_filter_add()
If the stream was read twice, the second time the callback wasn't called and
the header wasn't modified.

diffstat:

 src/lib-mail/istream-header-filter.c      |  11 ++++-
 src/lib-mail/test-istream-header-filter.c |  54 +++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 3 deletions(-)

diffs (109 lines):

diff -r 86f535375750 -r aa8786771490 src/lib-mail/istream-header-filter.c
--- a/src/lib-mail/istream-header-filter.c	Tue Apr 28 11:27:04 2015 +0200
+++ b/src/lib-mail/istream-header-filter.c	Tue Apr 28 14:20:39 2015 +0200
@@ -31,6 +31,7 @@
 	unsigned int header_read:1;
 	unsigned int seen_eoh:1;
 	unsigned int header_parsed:1;
+	unsigned int headers_edited:1;
 	unsigned int exclude:1;
 	unsigned int crlf:1;
 	unsigned int crlf_preserve:1;
@@ -209,14 +210,17 @@
 				  bsearch_strcasecmp) != NULL;
 		if (mstream->callback == NULL) {
 			/* nothing gets excluded */
-		} else if (mstream->cur_line > mstream->parsed_lines) {
-			/* first time in this line */
+		} else if (mstream->cur_line > mstream->parsed_lines ||
+			   mstream->headers_edited) {
+			/* first time in this line or we have actually modified
+			   the header so we always want to call the callbacks */
 			bool orig_matched = matched;
 
 			mstream->parsed_lines = mstream->cur_line;
 			mstream->callback(mstream, hdr, &matched,
 					  mstream->context);
-			if (matched != orig_matched) {
+			if (matched != orig_matched &&
+			    !mstream->headers_edited) {
 				i_array_init(&mstream->match_change_lines, 8);
 				array_append(&mstream->match_change_lines,
 					     &mstream->cur_line, 1);
@@ -583,4 +587,5 @@
 				const void *data, size_t size)
 {
 	buffer_append(input->hdr_buf, data, size);
+	input->headers_edited = TRUE;
 }
diff -r 86f535375750 -r aa8786771490 src/lib-mail/test-istream-header-filter.c
--- a/src/lib-mail/test-istream-header-filter.c	Tue Apr 28 11:27:04 2015 +0200
+++ b/src/lib-mail/test-istream-header-filter.c	Tue Apr 28 14:20:39 2015 +0200
@@ -68,6 +68,59 @@
 	test_end();
 }
 
+static void ATTR_NULL(3)
+edit_callback(struct header_filter_istream *input,
+	      struct message_header_line *hdr,
+	      bool *matched, void *context ATTR_UNUSED)
+{
+	if (hdr != NULL && strcasecmp(hdr->name, "To") == 0) {
+		/* modify To header */
+		const char *new_to = "To: 123\n";
+		*matched = TRUE;
+		i_stream_header_filter_add(input, new_to, strlen(new_to));
+	}
+}
+
+static void test_istream_edit(void)
+{
+	const char *input = "From: foo\nTo: bar\n\nhello world\n";
+	const char *output = "From: foo\nTo: 123\n\nhello world\n";
+	struct istream *istream, *filter;
+	unsigned int i, input_len = strlen(input);
+	unsigned int output_len = strlen(output);
+	const unsigned char *data;
+	size_t size;
+
+	test_begin("i_stream_create_header_filter(edit)");
+	istream = test_istream_create(input);
+	filter = i_stream_create_header_filter(istream,
+					       HEADER_FILTER_EXCLUDE |
+					       HEADER_FILTER_NO_CR,
+					       NULL, 0,
+					       edit_callback, (void *)NULL);
+	for (i = 1; i < input_len; i++) {
+		test_istream_set_size(istream, i);
+		test_assert(i_stream_read(filter) >= 0);
+	}
+	test_istream_set_size(istream, input_len);
+	test_assert(i_stream_read(filter) > 0);
+	test_assert(i_stream_read(filter) == -1);
+
+	data = i_stream_get_data(filter, &size);
+	test_assert(size == output_len && memcmp(data, output, size) == 0);
+
+	i_stream_skip(filter, size);
+	i_stream_seek(filter, 0);
+	while (i_stream_read(filter) > 0) ;
+	data = i_stream_get_data(filter, &size);
+	test_assert(size == output_len && memcmp(data, output, size) == 0);
+
+	i_stream_unref(&filter);
+	i_stream_unref(&istream);
+
+	test_end();
+}
+
 static void test_istream_end_body_with_lf(void)
 {
 	static const char *empty_strarray[] = { NULL };
@@ -131,6 +184,7 @@
 {
 	static void (*test_functions[])(void) = {
 		test_istream_filter,
+		test_istream_edit,
 		test_istream_end_body_with_lf,
 		NULL
 	};


More information about the dovecot-cvs mailing list