dovecot-2.2: Merged changes from v2.1 tree.

dovecot at dovecot.org dovecot at dovecot.org
Sat Feb 16 18:57:46 EET 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/e63d1cf19ec7
changeset: 15814:e63d1cf19ec7
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Feb 16 18:57:33 2013 +0200
description:
Merged changes from v2.1 tree.

diffstat:

 .hgsigs                                          |   2 +
 .hgtags                                          |   2 +
 src/imap/imap-client.c                           |   2 +
 src/lib-index/mail-cache-fields.c                |   2 +
 src/lib-index/mail-cache-lookup.c                |  13 +++----
 src/lib-index/mail-cache.c                       |  24 +++++++++++++-
 src/lib-storage/index/dbox-common/dbox-storage.c |   6 +++
 src/lib-storage/index/index-mail-headers.c       |   6 +++-
 src/lib-storage/index/index-mail.c               |  39 +++++++++++++++++++++--
 src/lib-storage/index/index-mail.h               |   1 +
 src/lib-storage/mail-storage.c                   |   8 +++-
 src/lib/Makefile.am                              |   1 +
 src/lib/buffer.c                                 |  11 +++++-
 src/lib/istream-tee.c                            |   1 +
 src/lib/str.c                                    |   3 -
 src/lib/test-lib.c                               |   1 +
 src/lib/test-lib.h                               |   1 +
 src/lib/test-str.c                               |  26 ++++++++++++++++
 src/lmtp/client.c                                |  22 ++++++++++++-
 src/lmtp/client.h                                |   2 +
 src/lmtp/commands.c                              |   8 ++--
 src/plugins/acl/doveadm-acl.c                    |  29 +++++++++++++++++
 22 files changed, 182 insertions(+), 28 deletions(-)

diffs (truncated from 568 to 300 lines):

diff -r 890b5b52ffd0 -r e63d1cf19ec7 .hgsigs
--- a/.hgsigs	Sat Feb 16 18:24:28 2013 +0200
+++ b/.hgsigs	Sat Feb 16 18:57:33 2013 +0200
@@ -55,3 +55,5 @@
 75bfda4a7c6c9aa04b6a6ef233fc527356171a06 0 iEYEABECAAYFAlC4WKwACgkQyUhSUUBViskaOACgmcwWV8hgsCOWvkbdh0OIw1ImSQYAn1RcTL0CG3M8+XG7QrrxSfQ7+V99
 86bccdf46d172524ca19a1a8a16a50ac30a6743c 0 iEYEABECAAYFAlDqonoACgkQyUhSUUBVisnqqACfaqdR6GxUAJznotKT9WHIUVhVgcIAoJIEa0SBzlGIWThmLvtQByF9vXcc
 cf9d62fd0b143efa8e49fac998eb78a648cdd8a9 0 iEYEABECAAYFAlDqjXUACgkQyUhSUUBViskUEwCfYTWHeDmPr8HfxSBQN17SD5IwDygAnROhb3IVTm9niDun4gxPxbHLo/Pe
+b314c97d4bbffd01b20f8492592aa422c13e3d55 0 iEYEABECAAYFAlEJlGMACgkQyUhSUUBVismNdQCgggPP/dt1duU1CMYfkpE4Kyc9Ju0An0kphokRqrtppkeqg7pF1JR01Mgq
+fc75811f3c08d80ed339cbb4d37c66f549542ba7 0 iEYEABECAAYFAlEU+CEACgkQyUhSUUBViskh9QCgnqPHUkNvtOioWxo4W7fXjCFLVAwAnR9Z26jgBpoejXDkgwT07wdfYiL3
diff -r 890b5b52ffd0 -r e63d1cf19ec7 .hgtags
--- a/.hgtags	Sat Feb 16 18:24:28 2013 +0200
+++ b/.hgtags	Sat Feb 16 18:57:33 2013 +0200
@@ -92,3 +92,5 @@
 75bfda4a7c6c9aa04b6a6ef233fc527356171a06 2.1.12
 cf9d62fd0b143efa8e49fac998eb78a648cdd8a9 2.1.13
 86bccdf46d172524ca19a1a8a16a50ac30a6743c 2.2.beta1
+b314c97d4bbffd01b20f8492592aa422c13e3d55 2.1.14
+fc75811f3c08d80ed339cbb4d37c66f549542ba7 2.1.15
diff -r 890b5b52ffd0 -r e63d1cf19ec7 src/imap/imap-client.c
--- a/src/imap/imap-client.c	Sat Feb 16 18:24:28 2013 +0200
+++ b/src/imap/imap-client.c	Sat Feb 16 18:57:33 2013 +0200
@@ -83,6 +83,8 @@
 					   set->imap_max_line_length, FALSE);
 	client->output = o_stream_create_fd(fd_out, (size_t)-1, FALSE);
 	o_stream_set_no_error_handling(client->output, TRUE);
+	i_stream_set_name(client->input, "<imap client>");
+	o_stream_set_name(client->output, "<imap client>");
 
 	o_stream_set_flush_callback(client->output, client_output, client);
 
diff -r 890b5b52ffd0 -r e63d1cf19ec7 src/lib-index/mail-cache-fields.c
--- a/src/lib-index/mail-cache-fields.c	Sat Feb 16 18:24:28 2013 +0200
+++ b/src/lib-index/mail-cache-fields.c	Sat Feb 16 18:57:33 2013 +0200
@@ -280,6 +280,8 @@
 			file_cache_invalidate(cache->file_cache, offset,
 					      field_hdr_size);
 		}
+		if (cache->read_buf != NULL)
+			buffer_set_used_size(cache->read_buf, 0);
 		ret = mail_cache_map(cache, offset, field_hdr_size, &data);
 		if (ret < 0)
 			return -1;
diff -r 890b5b52ffd0 -r e63d1cf19ec7 src/lib-index/mail-cache-lookup.c
--- a/src/lib-index/mail-cache-lookup.c	Sat Feb 16 18:24:28 2013 +0200
+++ b/src/lib-index/mail-cache-lookup.c	Sat Feb 16 18:57:33 2013 +0200
@@ -15,6 +15,7 @@
 {
 	const struct mail_cache_record *rec;
 	const void *data;
+	int ret;
 
 	i_assert(offset != 0);
 
@@ -41,17 +42,15 @@
 	}
 	if (rec->size > CACHE_PREFETCH) {
 		/* larger than we guessed. map the rest of the record. */
-		if (mail_cache_map(cache, offset, rec->size, &data) < 0)
+		if ((ret = mail_cache_map(cache, offset, rec->size, &data)) < 0)
 			return -1;
+		if (ret == 0) {
+			mail_cache_set_corrupted(cache, "record points outside file");
+			return -1;
+		}
 		rec = data;
 	}
 
-	if (rec->size > cache->mmap_length ||
-	    offset + rec->size > cache->mmap_length) {
-		mail_cache_set_corrupted(cache, "record points outside file");
-		return -1;
-	}
-
 	*rec_r = rec;
 	return 0;
 }
diff -r 890b5b52ffd0 -r e63d1cf19ec7 src/lib-index/mail-cache.c
--- a/src/lib-index/mail-cache.c	Sat Feb 16 18:24:28 2013 +0200
+++ b/src/lib-index/mail-cache.c	Sat Feb 16 18:57:33 2013 +0200
@@ -370,12 +370,30 @@
 int mail_cache_map(struct mail_cache *cache, size_t offset, size_t size,
 		   const void **data_r)
 {
+	struct stat st;
 	const void *data;
 	ssize_t ret;
 
 	if (size == 0)
 		size = sizeof(struct mail_cache_header);
 
+	/* verify offset + size before trying to allocate a huge amount of
+	   memory due to them. note that we may be prefetching more than we
+	   actually need, so don't fail too early. */
+	if ((size > cache->mmap_length || offset + size > cache->mmap_length) &&
+	    (offset > 0 || size > sizeof(struct mail_cache_header))) {
+		if (fstat(cache->fd, &st) < 0) {
+			i_error("fstat(%s) failed: %m", cache->filepath);
+			return -1;
+		}
+		if (offset >= (uoff_t)st.st_size) {
+			*data_r = NULL;
+			return 0;
+		}
+		if (offset + size > (uoff_t)st.st_size)
+			size = st.st_size - offset;
+	}
+
 	cache->remap_counter++;
 	if (cache->map_with_read)
 		return mail_cache_map_with_read(cache, offset, size, data_r);
@@ -432,6 +450,7 @@
 	cache->mmap_base = mmap_ro_file(cache->fd, &cache->mmap_length);
 	if (cache->mmap_base == MAP_FAILED) {
 		cache->mmap_base = NULL;
+		cache->mmap_length = 0;
 		mail_cache_set_syscall_error(cache, "mmap()");
 		return -1;
 	}
@@ -464,8 +483,7 @@
 
 	mail_cache_init_file_cache(cache);
 
-	if (mail_cache_map(cache, 0, sizeof(struct mail_cache_header),
-			   &data) < 0)
+	if (mail_cache_map(cache, 0, 0, &data) < 0)
 		return -1;
 	return 1;
 }
@@ -685,6 +703,8 @@
 			file_cache_invalidate(cache->file_cache, 0,
 					      sizeof(struct mail_cache_header));
 		}
+		if (cache->read_buf != NULL)
+			buffer_set_used_size(cache->read_buf, 0);
 		if (mail_cache_map(cache, 0, 0, &data) > 0)
 			cache->hdr_copy = *cache->hdr;
 		else {
diff -r 890b5b52ffd0 -r e63d1cf19ec7 src/lib-storage/index/dbox-common/dbox-storage.c
--- a/src/lib-storage/index/dbox-common/dbox-storage.c	Sat Feb 16 18:24:28 2013 +0200
+++ b/src/lib-storage/index/dbox-common/dbox-storage.c	Sat Feb 16 18:57:33 2013 +0200
@@ -270,6 +270,12 @@
 	if (mailbox_open(box) < 0)
 		return -1;
 
+	if (mail_index_get_header(box->view)->uid_validity != 0) {
+		mail_storage_set_error(box->storage, MAIL_ERROR_EXISTS,
+				       "Mailbox already exists");
+		return -1;
+	}
+
 	/* if alt path already exists and contains files, rebuild storage so
 	   that we don't start overwriting files. */
 	ret = mailbox_get_path_to(box, MAILBOX_LIST_PATH_TYPE_ALT_MAILBOX, &alt_path);
diff -r 890b5b52ffd0 -r e63d1cf19ec7 src/lib-storage/index/index-mail-headers.c
--- a/src/lib-storage/index/index-mail-headers.c	Sat Feb 16 18:24:28 2013 +0200
+++ b/src/lib-storage/index/index-mail-headers.c	Sat Feb 16 18:57:33 2013 +0200
@@ -374,6 +374,7 @@
 	input2 = tee_i_stream_create_child(mail->data.tee_stream);
 
 	index_mail_parse_header_init(mail, NULL);
+	mail->data.parser_input = input;
 	mail->data.parser_ctx =
 		message_parser_init(mail->mail.data_pool, input,
 				    hdr_parser_flags, msg_parser_flags);
@@ -386,10 +387,13 @@
 	struct index_mail_data *data = &mail->data;
 	struct message_part *parts;
 
-	if (data->parser_ctx != NULL)
+	if (data->parser_ctx != NULL) {
+		data->parser_input = NULL;
 		(void)message_parser_deinit(&data->parser_ctx, &parts);
+	}
 
 	if (data->parts == NULL) {
+		data->parser_input = data->stream;
 		data->parser_ctx = message_parser_init(mail->mail.data_pool,
 						       data->stream,
 						       hdr_parser_flags,
diff -r 890b5b52ffd0 -r e63d1cf19ec7 src/lib-storage/index/index-mail.c
--- a/src/lib-storage/index/index-mail.c	Sat Feb 16 18:24:28 2013 +0200
+++ b/src/lib-storage/index/index-mail.c	Sat Feb 16 18:57:33 2013 +0200
@@ -805,13 +805,43 @@
 static int index_mail_parse_body_finish(struct index_mail *mail,
 					enum index_cache_field field)
 {
-	if (message_parser_deinit(&mail->data.parser_ctx,
-				  &mail->data.parts) < 0) {
-		mail_set_cache_corrupted(&mail->mail.mail,
-					 MAIL_FETCH_MESSAGE_PARTS);
+	struct istream *parser_input = mail->data.parser_input;
+	int ret;
+
+	if (parser_input == NULL) {
+		ret = message_parser_deinit(&mail->data.parser_ctx,
+					    &mail->data.parts) < 0 ? 0 : 1;
+	} else {
+		mail->data.parser_input = NULL;
+		i_stream_ref(parser_input);
+		ret = message_parser_deinit(&mail->data.parser_ctx,
+					    &mail->data.parts) < 0 ? 0 : 1;
+		if (parser_input->stream_errno == 0 ||
+		    parser_input->stream_errno == EPIPE) {
+			/* EPIPE = input already closed. allow the caller to
+			   decide if that is an error or not. */
+			i_assert(i_stream_read(parser_input) == -1 &&
+				 !i_stream_have_bytes_left(parser_input));
+		} else {
+			errno = parser_input->stream_errno;
+			mail_storage_set_critical(mail->mail.mail.box->storage,
+				"mail parser: read(%s, box=%s) failed: %m",
+				i_stream_get_name(parser_input),
+				mail->mail.mail.box->vname);
+			ret = -1;
+		}
+		i_stream_unref(&parser_input);
+	}
+	if (ret <= 0) {
+		if (ret == 0) {
+			mail_set_cache_corrupted(&mail->mail.mail,
+						 MAIL_FETCH_MESSAGE_PARTS);
+		}
+		mail->data.parts = NULL;
 		mail->data.parsed_bodystructure = FALSE;
 		return -1;
 	}
+
 	if (mail->data.no_caching) {
 		/* if we're here because we aborted parsing, don't get any
 		   further or we may crash while generating output from
@@ -1221,6 +1251,7 @@
 			mail_set_cache_corrupted(&mail->mail.mail,
 						 MAIL_FETCH_MESSAGE_PARTS);
 		}
+		mail->data.parser_input = NULL;
 	}
 	if (data->filter_stream != NULL)
 		i_stream_unref(&data->filter_stream);
diff -r 890b5b52ffd0 -r e63d1cf19ec7 src/lib-storage/index/index-mail.h
--- a/src/lib-storage/index/index-mail.h	Sat Feb 16 18:24:28 2013 +0200
+++ b/src/lib-storage/index/index-mail.h	Sat Feb 16 18:57:33 2013 +0200
@@ -98,6 +98,7 @@
 	struct istream *stream, *filter_stream;
 	struct tee_istream *tee_stream;
 	struct message_size hdr_size, body_size;
+	struct istream *parser_input;
 	struct message_parser_ctx *parser_ctx;
 	int parsing_count;
 	ARRAY_TYPE(keywords) keywords;
diff -r 890b5b52ffd0 -r e63d1cf19ec7 src/lib-storage/mail-storage.c
--- a/src/lib-storage/mail-storage.c	Sat Feb 16 18:24:28 2013 +0200
+++ b/src/lib-storage/mail-storage.c	Sat Feb 16 18:57:33 2013 +0200
@@ -641,10 +641,12 @@
 
 	i_assert(uni_utf8_str_is_valid(vname));
 
-	if ((list->ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0 &&
-	    strncasecmp(vname, "INBOX", 5) == 0 &&
+	if (strncasecmp(vname, "INBOX", 5) == 0 &&
 	    strncmp(vname, "INBOX", 5) != 0) {
-		/* make sure INBOX shows up in uppercase everywhere */
+		/* make sure INBOX shows up in uppercase everywhere. do this
+		   regardless of whether we're in inbox=yes namespace, because
+		   clients expect INBOX to be case insensitive regardless of
+		   server's internal configuration. */
 		if (vname[5] == '\0')
 			vname = "INBOX";
 		else if (vname[5] == mail_namespace_get_sep(list->ns))
diff -r 890b5b52ffd0 -r e63d1cf19ec7 src/lib/Makefile.am
--- a/src/lib/Makefile.am	Sat Feb 16 18:24:28 2013 +0200
+++ b/src/lib/Makefile.am	Sat Feb 16 18:57:33 2013 +0200
@@ -286,6 +286,7 @@
 	test-primes.c \
 	test-priorityq.c \
 	test-seq-range-array.c \
+	test-str.c \
 	test-strescape.c \
 	test-strfuncs.c \
 	test-str-find.c \
diff -r 890b5b52ffd0 -r e63d1cf19ec7 src/lib/buffer.c
--- a/src/lib/buffer.c	Sat Feb 16 18:24:28 2013 +0200
+++ b/src/lib/buffer.c	Sat Feb 16 18:57:33 2013 +0200
@@ -39,6 +39,7 @@
 static inline void
 buffer_check_limits(struct real_buffer *buf, size_t pos, size_t data_size)
 {
+	unsigned int extra;
 	size_t new_size;
 
 	if (unlikely((size_t)-1 - pos < data_size)) {
@@ -53,7 +54,13 @@
 
 		memset(buf->w_buffer + buf->used, 0, max - buf->used);
 	}
-	if (new_size > buf->alloc) {
+
+	/* always keep +1 byte allocated available in case str_c() is called
+	   for this buffer. this is mainly for cases where the buffer is
+	   allocated from data stack, and str_c() is called in a separate stack
+	   frame. */


More information about the dovecot-cvs mailing list