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