dovecot-2.1: layout=fs: Rename mailbox names that aren't valid U...

dovecot at dovecot.org dovecot at dovecot.org
Wed Mar 14 16:24:58 EET 2012


details:   http://hg.dovecot.org/dovecot-2.1/rev/c077ca9bc306
changeset: 14309:c077ca9bc306
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Mar 14 16:24:05 2012 +0200
description:
layout=fs: Rename mailbox names that aren't valid UTF-8 to avoid crashes later.

diffstat:

 src/lib-storage/list/mailbox-list-fs-iter.c |  43 ++++++++++++++++++++++++++--
 1 files changed, 40 insertions(+), 3 deletions(-)

diffs (78 lines):

diff -r 3550dfc4af29 -r c077ca9bc306 src/lib-storage/list/mailbox-list-fs-iter.c
--- a/src/lib-storage/list/mailbox-list-fs-iter.c	Wed Mar 14 15:40:58 2012 +0200
+++ b/src/lib-storage/list/mailbox-list-fs-iter.c	Wed Mar 14 16:24:05 2012 +0200
@@ -2,12 +2,16 @@
 
 #include "lib.h"
 #include "array.h"
+#include "str.h"
+#include "unichar.h"
 #include "imap-match.h"
+#include "imap-utf7.h"
 #include "mail-storage.h"
 #include "mailbox-tree.h"
 #include "mailbox-list-subscriptions.h"
 #include "mailbox-list-fs.h"
 
+#include <stdio.h>
 #include <ctype.h>
 #include <dirent.h>
 #include <sys/stat.h>
@@ -508,6 +512,33 @@
 	return strcmp(path, inbox_path) == 0;
 }
 
+static void
+fs_list_rename_invalid(struct fs_list_iterate_context *ctx,
+		       const char *storage_name)
+{
+	/* the storage_name is completely invalid, rename it to
+	   something more sensible. we could do this for all names that
+	   aren't valid mUTF-7, but that might lead to accidents in
+	   future when UTF-8 storage names are used */
+	string_t *destname = t_str_new(128);
+	string_t *dest = t_str_new(128);
+	const char *root, *src;
+
+	root = mailbox_list_get_path(ctx->ctx.list, NULL,
+				     MAILBOX_LIST_PATH_TYPE_MAILBOX);
+	src = t_strconcat(root, "/", storage_name, NULL);
+
+	(void)uni_utf8_get_valid_data((const void *)storage_name,
+				      strlen(storage_name), destname);
+
+	str_append(dest, root);
+	str_append_c(dest, '/');
+	(void)imap_utf8_to_utf7(str_c(destname), dest);
+
+	if (rename(src, str_c(dest)) < 0 && errno != ENOENT)
+		i_error("rename(%s, %s) failed: %m", src, str_c(dest));
+}
+
 static int
 fs_list_entry(struct fs_list_iterate_context *ctx,
 	      const struct list_dir_entry *entry)
@@ -515,14 +546,20 @@
 	struct mail_namespace *ns = ctx->ctx.list->ns;
 	struct list_dir_context *dir, *subdir = NULL;
 	enum imap_match_result match, child_dir_match;
-	const char *storage_name, *child_dir_name;
+	const char *storage_name, *vname, *child_dir_name;
 
 	dir = ctx->dir;
 	storage_name = *dir->storage_name == '\0' ? entry->fname :
 		t_strconcat(dir->storage_name, "/", entry->fname, NULL);
 
-	ctx->info.name = mailbox_list_get_vname(ctx->ctx.list, storage_name);
-	ctx->info.name = p_strdup(ctx->info_pool, ctx->info.name);
+	vname = mailbox_list_get_vname(ctx->ctx.list, storage_name);
+	if (!uni_utf8_str_is_valid(vname)) {
+		fs_list_rename_invalid(ctx, storage_name);
+		/* just skip this in this iteration, we'll see it on the
+		   next list */
+		return 0;
+	}
+	ctx->info.name = p_strdup(ctx->info_pool, vname);
 	ctx->info.flags = entry->info_flags;
 
 	match = imap_match(ctx->ctx.glob, ctx->info.name);


More information about the dovecot-cvs mailing list