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