dovecot-2.2: lib-mail: Fixed message_part_to_idx()

dovecot at dovecot.org dovecot at dovecot.org
Sun Jul 19 13:45:38 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/012a355f9f8a
changeset: 18915:012a355f9f8a
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Jul 19 16:45:23 2015 +0300
description:
lib-mail: Fixed message_part_to_idx()

diffstat:

 src/lib-mail/message-part.c      |  39 ++++++++++++++++++++++++++++++---------
 src/lib-mail/test-message-part.c |  31 ++++++++++++++++++++++++++-----
 2 files changed, 56 insertions(+), 14 deletions(-)

diffs (119 lines):

diff -r a83cc1411205 -r 012a355f9f8a src/lib-mail/message-part.c
--- a/src/lib-mail/message-part.c	Sun Jul 19 16:21:04 2015 +0300
+++ b/src/lib-mail/message-part.c	Sun Jul 19 16:45:23 2015 +0300
@@ -3,18 +3,39 @@
 #include "lib.h"
 #include "message-part.h"
 
+static const struct message_part *
+message_part_root(const struct message_part *part)
+{
+	while (part->parent != NULL)
+		part = part->parent;
+	return part;
+}
+
+static bool message_part_find(const struct message_part *siblings,
+			      const struct message_part *part,
+			      unsigned int *n)
+{
+	const struct message_part *p;
+
+	for (p = siblings; p != NULL; p = p->next) {
+		if (p == part)
+			return TRUE;
+		*n += 1;
+		if (message_part_find(p->children, part, n))
+			return TRUE;
+	}
+	return FALSE;
+}
+
 unsigned int message_part_to_idx(const struct message_part *part)
 {
-	const struct message_part *p;
-	unsigned int n;
+	const struct message_part *root;
+	unsigned int n = 0;
 
-	if (part->parent == NULL) {
-		/* root */
-		return 0;
-	}
-	for (n = 0, p = part->parent->children; p != part; p = p->next, n++)
-		;
-	return n + 1 + message_part_to_idx(part->parent);
+	root = message_part_root(part);
+	if (!message_part_find(root, part, &n))
+		i_unreached();
+	return n;
 }
 
 static struct message_part *
diff -r a83cc1411205 -r 012a355f9f8a src/lib-mail/test-message-part.c
--- a/src/lib-mail/test-message-part.c	Sun Jul 19 16:21:04 2015 +0300
+++ b/src/lib-mail/test-message-part.c	Sun Jul 19 16:45:23 2015 +0300
@@ -34,13 +34,30 @@
 "<p>Hello world</p>\n"
 "\n"
 "--sub1\n"
-"Content-Type: text/plain\n"
+"Content-Type: multipart/alternative; boundary=\"sub2\"\n"
 "\n"
-"Hello another world\n"
+"--sub2\n"
+"Content-Type: multipart/alternative; boundary=\"sub3\"\n"
 "\n"
+"--sub3\n"
+"\n"
+"sub3 text\n"
+"--sub3\n"
+"\n"
+"sub3 text2\n"
+"--sub3--\n"
+"\n"
+"sub2 text\n"
+"--sub2\n"
+"\n"
+"sub2 text2\n"
 "--sub1--\n"
 "Sub MIME epilogue\n"
 "\n"
+"--foo bar\n"
+"Content-Type: text/plain\n"
+"\n"
+"Another part\n"
 "--foo bar--\n"
 "Root MIME epilogue\n"
 "\n";
@@ -52,7 +69,7 @@
 	struct istream *input;
 	struct message_part *parts, *part, *prev_part;
 	struct message_block block;
-	unsigned int i;
+	unsigned int i, prev_idx = 0, part_idx;
 	pool_t pool;
 	int ret;
 
@@ -61,7 +78,11 @@
 	input = i_stream_create_from_data(test_msg, TEST_MSG_LEN);
 
 	parser = message_parser_init(pool, input, 0, 0);
-	while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
+	while ((ret = message_parser_parse_next_block(parser, &block)) > 0) {
+		part_idx = message_part_to_idx(block.part);
+		test_assert(part_idx >= prev_idx);
+		prev_idx = part_idx;
+	}
 	test_assert(ret < 0);
 	test_assert(message_parser_deinit(&parser, &parts) == 0);
 
@@ -69,7 +90,7 @@
 	test_assert(part == parts);
 	test_assert(message_part_by_idx(parts, 1) == parts->children);
 
-	for (i = 1; i < 6; i++) {
+	for (i = 1; i < 11; i++) {
 		prev_part = part;
 		part = message_part_by_idx(parts, i);
 		test_assert(part != NULL);


More information about the dovecot-cvs mailing list