From: Timo Sirainen Date: Tue, 1 Feb 2011 18:41:54 +0000 (+0200) Subject: lib-storage: Mailbox virtual names are now in UTF-8 format, not IMAP mUTF-7. X-Git-Tag: 2.1.alpha1~376 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=636f017be100bce67d66fd3ae1544a47681efd33;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Mailbox virtual names are now in UTF-8 format, not IMAP mUTF-7. Plugins that use mailbox names in configuration now take them also as UTF-8 rather than mUTF-7. --- diff --git a/src/doveadm/doveadm-mail-fetch.c b/src/doveadm/doveadm-mail-fetch.c index c8d796f177..487d491bcf 100644 --- a/src/doveadm/doveadm-mail-fetch.c +++ b/src/doveadm/doveadm-mail-fetch.c @@ -6,7 +6,6 @@ #include "ostream.h" #include "str.h" #include "message-size.h" -#include "imap-utf7.h" #include "imap-util.h" #include "mail-user.h" #include "mail-storage.h" @@ -47,17 +46,11 @@ static int fetch_user(struct fetch_cmd_context *ctx) static int fetch_mailbox(struct fetch_cmd_context *ctx) { const char *value; - string_t *str = t_str_new(128); if (mail_get_special(ctx->mail, MAIL_FETCH_MAILBOX_NAME, &value) < 0) return -1; - if (imap_utf7_to_utf8(value, str) == 0) - doveadm_print(str_c(str)); - else { - /* not a valid mUTF-7 name, fallback to showing it as-is */ - doveadm_print(value); - } + doveadm_print(value); return 0; } diff --git a/src/doveadm/doveadm-mail-mailbox-status.c b/src/doveadm/doveadm-mail-mailbox-status.c index 8a5fa6b045..49b4f1007c 100644 --- a/src/doveadm/doveadm-mail-mailbox-status.c +++ b/src/doveadm/doveadm-mail-mailbox-status.c @@ -4,7 +4,6 @@ #include "str.h" #include "mail-namespace.h" #include "mail-storage.h" -#include "imap-utf7.h" #include "doveadm-print.h" #include "doveadm-mail.h" #include "doveadm-mail-list-iter.h" @@ -80,16 +79,8 @@ static void status_output(struct status_cmd_context *ctx, struct mailbox *box, const struct mailbox_status *status, const struct mailbox_metadata *metadata) { - string_t *name; - - if (box != NULL) { - name = t_str_new(128); - if (imap_utf7_to_utf8(mailbox_get_vname(box), name) < 0) { - str_truncate(name, 0); - str_append(name, mailbox_get_vname(box)); - } - doveadm_print(str_c(name)); - } + if (box != NULL) + doveadm_print(mailbox_get_vname(box)); if ((ctx->status_items & STATUS_MESSAGES) != 0) doveadm_print_num(status->messages); @@ -128,14 +119,8 @@ status_mailbox(struct status_cmd_context *ctx, const struct mailbox_info *info) struct mailbox *box; struct mailbox_status status; struct mailbox_metadata metadata; - string_t *mailbox_name = t_str_new(128); - - if (imap_utf7_to_utf8(info->name, mailbox_name) < 0) { - str_truncate(mailbox_name, 0); - str_append(mailbox_name, info->name); - } - box = doveadm_mailbox_find(ctx->ctx.cur_mail_user, str_c(mailbox_name)); + box = doveadm_mailbox_find(ctx->ctx.cur_mail_user, info->name); if (mailbox_get_status(box, ctx->status_items, &status) < 0 || mailbox_get_metadata(box, ctx->metadata_items, &metadata) < 0) { ctx->ctx.failed = TRUE; diff --git a/src/doveadm/doveadm-mail-mailbox.c b/src/doveadm/doveadm-mail-mailbox.c index 00a9f084e1..3e432c89cc 100644 --- a/src/doveadm/doveadm-mail-mailbox.c +++ b/src/doveadm/doveadm-mail-mailbox.c @@ -3,6 +3,7 @@ #include "lib.h" #include "array.h" #include "str.h" +#include "unichar.h" #include "imap-utf7.h" #include "mail-namespace.h" #include "mail-storage.h" @@ -34,24 +35,14 @@ struct list_cmd_context { bool mutf7; }; -const char *const *doveadm_mailbox_args_to_mutf7(const char *const args[]) +void doveadm_mailbox_args_check(const char *const args[]) { - ARRAY_TYPE(const_string) dest; - string_t *str; - const char *mutf7; unsigned int i; - str = t_str_new(128); - t_array_init(&dest, 8); for (i = 0; args[i] != NULL; i++) { - str_truncate(str, 0); - if (imap_utf8_to_utf7(args[i], str) < 0) + if (!uni_utf8_str_is_valid(args[i])) i_fatal("Mailbox name not valid UTF-8: %s", args[i]); - mutf7 = t_strdup(str_c(str)); - array_append(&dest, &mutf7, 1); } - (void)array_append_space(&dest); - return array_idx(&dest, 0); } static bool cmd_mailbox_parse_arg(struct doveadm_mail_cmd_context *_ctx, int c) @@ -122,11 +113,14 @@ cmd_mailbox_list_run(struct doveadm_mail_cmd_context *_ctx, iter = doveadm_mail_list_iter_full_init(user, ctx->search_args, iter_flags); while ((info = doveadm_mail_list_iter_next(iter)) != NULL) { - str_truncate(str, 0); - if (ctx->mutf7 || imap_utf7_to_utf8(info->name, str) < 0) + if (!ctx->mutf7) doveadm_print(info->name); - else + else { + str_truncate(str, 0); + if (imap_utf8_to_utf7(info->name, str) < 0) + i_unreached(); doveadm_print(str_c(str)); + } } doveadm_mail_list_iter_deinit(&iter); } @@ -138,7 +132,7 @@ doveadm_mail_mailbox_search_args_build(const char *const args[]) struct mail_search_arg *arg; unsigned int i; - args = doveadm_mailbox_args_to_mutf7(args); + doveadm_mailbox_args_check(args); search_args = mail_search_build_init(); for (i = 0; args[i] != NULL; i++) { arg = mail_search_build_add(search_args, SEARCH_MAILBOX_GLOB); @@ -227,7 +221,7 @@ static void cmd_mailbox_create_init(struct doveadm_mail_cmd_context *_ctx, if (args[0] == NULL) doveadm_mail_help_name("mailbox create"); - args = doveadm_mailbox_args_to_mutf7(args); + doveadm_mailbox_args_check(args); for (i = 0; args[i] != NULL; i++) { name = p_strdup(ctx->ctx.ctx.pool, args[i]); @@ -288,7 +282,7 @@ static void cmd_mailbox_delete_init(struct doveadm_mail_cmd_context *_ctx, if (args[0] == NULL) doveadm_mail_help_name("mailbox delete"); - args = doveadm_mailbox_args_to_mutf7(args); + doveadm_mailbox_args_check(args); for (i = 0; args[i] != NULL; i++) { name = p_strdup(ctx->ctx.ctx.pool, args[i]); @@ -352,7 +346,7 @@ static void cmd_mailbox_rename_init(struct doveadm_mail_cmd_context *_ctx, if (str_array_length(args) != 2) doveadm_mail_help_name("mailbox rename"); - args = doveadm_mailbox_args_to_mutf7(args); + doveadm_mailbox_args_check(args); ctx->oldname = p_strdup(ctx->ctx.ctx.pool, args[0]); ctx->newname = p_strdup(ctx->ctx.ctx.pool, args[1]); @@ -407,7 +401,7 @@ static void cmd_mailbox_subscribe_init(struct doveadm_mail_cmd_context *_ctx, "mailbox subscribe" : "mailbox unsubscribe"); } - args = doveadm_mailbox_args_to_mutf7(args); + doveadm_mailbox_args_check(args); for (i = 0; args[i] != NULL; i++) { name = p_strdup(ctx->ctx.ctx.pool, args[i]); diff --git a/src/doveadm/doveadm-mail.c b/src/doveadm/doveadm-mail.c index 098d5f31db..37060711bd 100644 --- a/src/doveadm/doveadm-mail.c +++ b/src/doveadm/doveadm-mail.c @@ -5,10 +5,10 @@ #include "lib-signals.h" #include "ioloop.h" #include "str.h" +#include "unichar.h" #include "module-dir.h" #include "wildcard-match.h" #include "master-service.h" -#include "imap-utf7.h" #include "mail-user.h" #include "mail-namespace.h" #include "mail-storage.h" @@ -75,12 +75,9 @@ struct mailbox * doveadm_mailbox_find(struct mail_user *user, const char *mailbox) { struct mail_namespace *ns; - string_t *str; - str = t_str_new(128); - if (imap_utf8_to_utf7(mailbox, str) < 0) + if (!uni_utf8_str_is_valid(mailbox)) i_fatal("Mailbox name not valid UTF-8: %s", mailbox); - mailbox = str_c(str); ns = mail_namespace_find(user->namespaces, mailbox); if (ns == NULL) diff --git a/src/doveadm/doveadm-mail.h b/src/doveadm/doveadm-mail.h index 4a8d4a1a1c..26a097a1ef 100644 --- a/src/doveadm/doveadm-mail.h +++ b/src/doveadm/doveadm-mail.h @@ -95,7 +95,7 @@ int doveadm_mailbox_find_and_sync(struct mail_user *user, const char *mailbox, struct mailbox **box_r); struct mail_search_args * doveadm_mail_build_search_args(const char *const args[]); -const char *const *doveadm_mailbox_args_to_mutf7(const char *const args[]); +void doveadm_mailbox_args_check(const char *const args[]); struct mail_search_args * doveadm_mail_mailbox_search_args_build(const char *const args[]); diff --git a/src/imap/cmd-list.c b/src/imap/cmd-list.c index 7aca23d4f4..06ca1be8e2 100644 --- a/src/imap/cmd-list.c +++ b/src/imap/cmd-list.c @@ -4,6 +4,7 @@ #include "array.h" #include "str.h" #include "strescape.h" +#include "imap-utf7.h" #include "imap-quote.h" #include "imap-match.h" #include "imap-status.h" @@ -383,11 +384,12 @@ list_namespace_mailboxes(struct cmd_list_context *ctx) const struct mailbox_info *info; struct mail_namespace *ns; enum mailbox_info_flags flags; - string_t *str; + string_t *str, *mutf7_name; const char *name; int ret = 0; str = t_str_new(256); + mutf7_name = t_str_new(128); while ((info = mailbox_list_iter_next(ctx->list_iter)) != NULL) { name = info->name; flags = info->flags; @@ -438,6 +440,10 @@ list_namespace_mailboxes(struct cmd_list_context *ctx) continue; } + str_truncate(mutf7_name, 0); + if (imap_utf8_to_utf7(name, mutf7_name) < 0) + i_panic("LIST: Mailbox name not UTF-8: %s", name); + str_truncate(str, 0); str_printfa(str, "* %s (", ctx->lsub ? "LSUB" : "LIST"); mailbox_flags2str(ctx, str, flags); @@ -445,7 +451,7 @@ list_namespace_mailboxes(struct cmd_list_context *ctx) list_reply_append_ns_sep_param(str, mail_namespace_get_sep(ctx->ns)); str_append_c(str, ' '); - imap_quote_append_string(str, name, FALSE); + imap_quote_append_string(str, str_c(mutf7_name), FALSE); mailbox_childinfo2str(ctx, str, flags); ret = client_send_line(ctx->cmd->client, str_c(str)); diff --git a/src/imap/cmd-subscribe.c b/src/imap/cmd-subscribe.c index 889c44deaf..8303a0dcb1 100644 --- a/src/imap/cmd-subscribe.c +++ b/src/imap/cmd-subscribe.c @@ -1,6 +1,7 @@ /* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */ #include "imap-common.h" +#include "imap-utf7.h" #include "imap-commands.h" #include "mail-namespace.h" @@ -22,12 +23,20 @@ subscribe_is_valid_name(struct client_command_context *cmd, struct mailbox *box) return TRUE; } +static bool str_ends_with_char(const char *str, char c) +{ + unsigned int len = strlen(str); + + return len > 0 && str[len-1] == c; +} + bool cmd_subscribe_full(struct client_command_context *cmd, bool subscribe) { struct mail_namespace *ns; struct mailbox *box, *box2; const char *mailbox, *orig_mailbox; bool unsubscribed_mailbox2; + char sep; /* */ if (!client_read_string_args(cmd, 1, &mailbox)) @@ -46,10 +55,14 @@ bool cmd_subscribe_full(struct client_command_context *cmd, bool subscribe) } } + sep = mail_namespace_get_sep(ns); unsubscribed_mailbox2 = FALSE; - if (!subscribe && mailbox != orig_mailbox) { + if (!subscribe && + str_ends_with_char(orig_mailbox, sep) && + !str_ends_with_char(mailbox, sep)) { /* try to unsubscribe both "box" and "box/" */ - box2 = mailbox_alloc(ns->list, orig_mailbox, 0); + const char *name2 = t_strdup_printf("%s%c", mailbox, sep); + box2 = mailbox_alloc(ns->list, name2, 0); if (mailbox_set_subscribed(box2, FALSE) == 0) unsubscribed_mailbox2 = TRUE; mailbox_free(&box2); diff --git a/src/imap/imap-commands-util.c b/src/imap/imap-commands-util.c index 4dfe9aba73..b66ff2f984 100644 --- a/src/imap/imap-commands-util.c +++ b/src/imap/imap-commands-util.c @@ -8,6 +8,7 @@ #include "imap-resp-code.h" #include "imap-parser.h" #include "imap-sync.h" +#include "imap-utf7.h" #include "imap-util.h" #include "mail-storage.h" #include "mail-namespace.h" @@ -19,6 +20,7 @@ client_find_namespace(struct client_command_context *cmd, const char **mailbox) struct mail_namespace *namespaces = cmd->client->user->namespaces; struct mail_namespace *ns; unsigned int name_len; + string_t *utf8_name; ns = mail_namespace_find(namespaces, *mailbox); if (ns == NULL) { @@ -37,6 +39,13 @@ client_find_namespace(struct client_command_context *cmd, const char **mailbox) /* drop the extra trailing hierarchy separator */ *mailbox = t_strndup(*mailbox, name_len-1); } + + utf8_name = t_str_new(64); + if (imap_utf7_to_utf8(*mailbox, utf8_name) < 0) { + client_send_tagline(cmd, "NO Mailbox name is not valid mUTF-7"); + return NULL; + } + *mailbox = str_c(utf8_name); return ns; } diff --git a/src/imap/imap-fetch.c b/src/imap/imap-fetch.c index ded6969c5a..5d773ddd50 100644 --- a/src/imap/imap-fetch.c +++ b/src/imap/imap-fetch.c @@ -9,6 +9,7 @@ #include "message-send.h" #include "message-size.h" #include "imap-date.h" +#include "imap-utf7.h" #include "mail-search-build.h" #include "imap-commands.h" #include "imap-quote.h" @@ -797,12 +798,18 @@ fetch_guid_init(struct imap_fetch_context *ctx ATTR_UNUSED, const char *name, static int fetch_x_mailbox(struct imap_fetch_context *ctx, struct mail *mail, void *context ATTR_UNUSED) { - const char *str; + const char *name; + string_t *mutf7_name; - if (mail_get_special(mail, MAIL_FETCH_MAILBOX_NAME, &str) < 0) + if (mail_get_special(mail, MAIL_FETCH_MAILBOX_NAME, &name) < 0) i_panic("mailbox name not returned"); + + mutf7_name = t_str_new(strlen(name)*2); + if (imap_utf8_to_utf7(name, mutf7_name) < 0) + i_panic("FETCH: Mailbox name not UTF-8: %s", name); + str_append(ctx->cur_str, "X-MAILBOX "); - imap_quote_append_string(ctx->cur_str, str, FALSE); + imap_quote_append_string(ctx->cur_str, str_c(mutf7_name), FALSE); str_append_c(ctx->cur_str, ' '); return 1; } diff --git a/src/lda/main.c b/src/lda/main.c index a3754d23bb..c77cd5c0b4 100644 --- a/src/lda/main.c +++ b/src/lda/main.c @@ -17,7 +17,6 @@ #include "unichar.h" #include "rfc822-parser.h" #include "message-address.h" -#include "imap-utf7.h" #include "settings-parser.h" #include "master-service.h" #include "master-service-settings.h" diff --git a/src/lib-lda/mail-deliver.c b/src/lib-lda/mail-deliver.c index 686e70592e..820b98e0e9 100644 --- a/src/lib-lda/mail-deliver.c +++ b/src/lib-lda/mail-deliver.c @@ -5,9 +5,9 @@ #include "array.h" #include "str.h" #include "str-sanitize.h" +#include "unichar.h" #include "var-expand.h" #include "message-address.h" -#include "imap-utf7.h" #include "lda-settings.h" #include "mail-storage.h" #include "mail-namespace.h" @@ -116,16 +116,6 @@ void mail_deliver_log(struct mail_deliver_context *ctx, const char *fmt, ...) va_end(args); } -static const char *mailbox_name_to_mutf7(const char *mailbox_utf8) -{ - string_t *str = t_str_new(128); - - if (imap_utf8_to_utf7(mailbox_utf8, str) < 0) - return mailbox_utf8; - else - return str_c(str); -} - int mail_deliver_save_open(struct mail_deliver_save_open_context *ctx, const char *name, struct mailbox **box_r, enum mail_error *error_r, const char **error_str_r) @@ -140,7 +130,12 @@ int mail_deliver_save_open(struct mail_deliver_save_open_context *ctx, *error_r = MAIL_ERROR_NONE; *error_str_r = NULL; - name = mailbox_name_to_mutf7(name); + if (!uni_utf8_str_is_valid(name)) { + *error_str_r = "Mailbox name not valid UTF-8"; + *error_r = MAIL_ERROR_PARAMS; + return -1; + } + ns = mail_namespace_find(ctx->user->namespaces, name); if (ns == NULL) { *error_str_r = "Unknown namespace"; diff --git a/src/lib-storage/mail-search-register-human.c b/src/lib-storage/mail-search-register-human.c index 8bdb96406f..fa7c0eb8c7 100644 --- a/src/lib-storage/mail-search-register-human.c +++ b/src/lib-storage/mail-search-register-human.c @@ -4,7 +4,7 @@ #include "ioloop.h" #include "array.h" #include "str.h" -#include "imap-utf7.h" +#include "unichar.h" #include "settings-parser.h" #include "imap-date.h" #include "mail-search-register.h" @@ -135,25 +135,15 @@ static struct mail_search_arg * human_search_mailbox(struct mail_search_build_context *ctx) { struct mail_search_arg *sarg; - const char *value; sarg = mail_search_build_str(ctx, SEARCH_MAILBOX_GLOB); if (sarg == NULL) return NULL; - value = sarg->value.str; - - T_BEGIN { - string_t *str = t_str_new(128); - - if (imap_utf8_to_utf7(value, str) < 0) - sarg->value.str = NULL; - else - sarg->value.str = p_strdup(ctx->pool, str_c(str)); - } T_END; - if (sarg->value.str == NULL) { + if (!uni_utf8_str_is_valid(sarg->value.str)) { ctx->_error = p_strconcat(ctx->pool, - "Mailbox name not valid UTF-8: ", value, NULL); + "Mailbox name not valid UTF-8: ", + sarg->value.str, NULL); return NULL; } return sarg; diff --git a/src/lib-storage/mail-search-register-imap.c b/src/lib-storage/mail-search-register-imap.c index d15abc1185..8929ad2053 100644 --- a/src/lib-storage/mail-search-register-imap.c +++ b/src/lib-storage/mail-search-register-imap.c @@ -3,8 +3,10 @@ #include "lib.h" #include "ioloop.h" #include "array.h" +#include "str.h" #include "imap-date.h" #include "imap-seqset.h" +#include "imap-utf7.h" #include "imap-util.h" #include "mail-search-register.h" #include "mail-search-parser.h" @@ -430,7 +432,25 @@ imap_search_inthread(struct mail_search_build_context *ctx) } CALLBACK_STR(x_guid, SEARCH_GUID); -CALLBACK_STR(x_mailbox, SEARCH_MAILBOX_GLOB); + +static struct mail_search_arg * +imap_search_x_mailbox(struct mail_search_build_context *ctx) +{ + struct mail_search_arg *sarg; + string_t *utf8_name; + + sarg = mail_search_build_str(ctx, SEARCH_MAILBOX_GLOB); + if (sarg == NULL) + return NULL; + + utf8_name = t_str_new(strlen(sarg->value.str)); + if (imap_utf7_to_utf8(sarg->value.str, utf8_name) < 0) { + ctx->_error = "X-MAILBOX name not mUTF-7"; + return NULL; + } + sarg->value.str = p_strdup(ctx->pool, str_c(utf8_name)); + return sarg; +} const struct mail_search_register_arg imap_register_args[] = { /* argument set operations */ diff --git a/src/lib-storage/mail-storage.c b/src/lib-storage/mail-storage.c index ed0842fffd..63aa41b55d 100644 --- a/src/lib-storage/mail-storage.c +++ b/src/lib-storage/mail-storage.c @@ -4,6 +4,7 @@ #include "ioloop.h" #include "array.h" #include "llist.h" +#include "unichar.h" #include "istream.h" #include "eacces-error.h" #include "mkdir-parents.h" @@ -570,6 +571,8 @@ struct mailbox *mailbox_alloc(struct mailbox_list *list, const char *vname, struct mail_storage *storage; struct mailbox *box; + i_assert(uni_utf8_str_is_valid(vname)); + if (mailbox_list_get_storage(&new_list, vname, &storage) < 0) { /* just use the first storage. FIXME: does this break? */ storage = list->ns->storage; diff --git a/src/lib-storage/mailbox-list.c b/src/lib-storage/mailbox-list.c index 601db276f0..03be5a0d84 100644 --- a/src/lib-storage/mailbox-list.c +++ b/src/lib-storage/mailbox-list.c @@ -350,37 +350,45 @@ const char *mailbox_list_default_get_storage_name(struct mailbox_list *list, { struct mail_namespace *ns = list->ns; unsigned int prefix_len = strlen(ns->prefix); + const char *storage_name = vname; + string_t *str; char list_sep, ns_sep, *ret, *p; - if (strcasecmp(vname, "INBOX") == 0) - vname = "INBOX"; + if (strcasecmp(storage_name, "INBOX") == 0) + storage_name = "INBOX"; if (prefix_len > 0) { /* skip namespace prefix, except if this is INBOX */ - if (strncmp(ns->prefix, vname, prefix_len) == 0) - vname += prefix_len; - else if (strncmp(ns->prefix, vname, prefix_len-1) == 0 && + if (strncmp(ns->prefix, storage_name, prefix_len) == 0) + storage_name += prefix_len; + else if (strncmp(ns->prefix, storage_name, prefix_len-1) == 0 && ns->prefix[prefix_len-1] == mail_namespace_get_sep(ns)) { /* trying to access the namespace prefix itself */ - vname = ""; + storage_name = ""; } else { - i_assert(strcmp(vname, "INBOX") == 0); + i_assert(strcmp(storage_name, "INBOX") == 0); } } + /* UTF-8 -> mUTF-7 conversion */ + str = t_str_new(strlen(storage_name)*2); + if (imap_utf8_to_utf7(storage_name, str) < 0) + i_panic("Mailbox name not UTF-8: %s", vname); + storage_name = str_c(str); + list_sep = mailbox_list_get_hierarchy_sep(list); ns_sep = mail_namespace_get_sep(ns); if (list_sep == ns_sep) - return vname; + return storage_name; if (ns->type == NAMESPACE_SHARED && (ns->flags & NAMESPACE_FLAG_AUTOCREATED) == 0) { /* shared namespace root. the backend storage's hierarchy separator isn't known yet, so do nothing. */ - return vname; + return storage_name; } - ret = p_strdup(unsafe_data_stack_pool, vname); + ret = p_strdup(unsafe_data_stack_pool, storage_name); for (p = ret; *p != '\0'; p++) { if (*p == ns_sep) *p = list_sep; @@ -398,15 +406,16 @@ const char *mailbox_list_default_get_vname(struct mailbox_list *list, const char *storage_name) { unsigned int i, prefix_len, name_len; + const char *vname = storage_name; char list_sep, ns_sep, *ret; if ((list->ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0 && - strcasecmp(storage_name, "INBOX") == 0 && + strcasecmp(vname, "INBOX") == 0 && list->ns->user == list->ns->owner) { /* user's INBOX - use as-is */ return "INBOX"; } - if (*storage_name == '\0') { + if (*vname == '\0') { /* return namespace prefix without the separator */ if (list->ns->prefix_len == 0) return list->ns->prefix; @@ -414,6 +423,11 @@ const char *mailbox_list_default_get_vname(struct mailbox_list *list, return t_strndup(list->ns->prefix, list->ns->prefix_len - 1); } + } else { + /* mUTF-7 -> UTF-8 conversion */ + string_t *str = t_str_new(strlen(vname)); + if (imap_utf7_to_utf8(vname, str) == 0) + vname = str_c(str); } prefix_len = strlen(list->ns->prefix); @@ -421,15 +435,15 @@ const char *mailbox_list_default_get_vname(struct mailbox_list *list, ns_sep = mail_namespace_get_sep(list->ns); if (list_sep == ns_sep && prefix_len == 0) - return storage_name; + return vname; /* @UNSAFE */ - name_len = strlen(storage_name); + name_len = strlen(vname); ret = t_malloc(prefix_len + name_len + 1); memcpy(ret, list->ns->prefix, prefix_len); for (i = 0; i < name_len; i++) { - ret[i + prefix_len] = storage_name[i] == list_sep ? ns_sep : - storage_name[i]; + ret[i + prefix_len] = + vname[i] == list_sep ? ns_sep : vname[i]; } ret[i + prefix_len] = '\0'; return ret; diff --git a/src/plugins/autocreate/autocreate-plugin.c b/src/plugins/autocreate/autocreate-plugin.c index 94bb9e6227..d84b9df75c 100644 --- a/src/plugins/autocreate/autocreate-plugin.c +++ b/src/plugins/autocreate/autocreate-plugin.c @@ -1,6 +1,7 @@ /* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "unichar.h" #include "mail-storage.h" #include "mail-storage-hooks.h" #include "mail-namespace.h" @@ -18,6 +19,11 @@ autocreate_mailbox(struct mail_namespace *namespaces, const char *name) const char *str; enum mail_error error; + if (!uni_utf8_str_is_valid(name)) { + i_error("autocreate: Mailbox name isn't valid UTF-8: %s", name); + return; + } + ns = mail_namespace_find(namespaces, name); if (ns == NULL) { if (namespaces->mail_set->mail_debug) @@ -61,6 +67,11 @@ autosubscribe_mailbox(struct mail_namespace *namespaces, const char *name) const char *str; enum mail_error error; + if (!uni_utf8_str_is_valid(name)) { + i_error("autocreate: Mailbox name isn't valid UTF-8: %s", name); + return; + } + ns = mail_namespace_find_subscribable(namespaces, name); if (ns == NULL) { if (namespaces->mail_set->mail_debug) diff --git a/src/plugins/snarf/snarf-plugin.c b/src/plugins/snarf/snarf-plugin.c index 44c0d01c83..573fa946d8 100644 --- a/src/plugins/snarf/snarf-plugin.c +++ b/src/plugins/snarf/snarf-plugin.c @@ -2,6 +2,7 @@ #include "lib.h" #include "array.h" +#include "unichar.h" #include "mail-namespace.h" #include "mail-search-build.h" #include "mail-storage-private.h" @@ -124,6 +125,10 @@ snarf_box_find(struct mail_user *user, struct mailbox_list **list_r, snarf_name = mail_user_plugin_getenv(user, "snarf"); if (snarf_name == NULL) return FALSE; + if (!uni_utf8_str_is_valid(snarf_name)) { + i_error("snarf: Mailbox name not UTF-8: %s", snarf_name); + return FALSE; + } snarf_ns = mail_namespace_find(user->namespaces, snarf_name); if (snarf_ns == NULL) { diff --git a/src/plugins/trash/trash-plugin.c b/src/plugins/trash/trash-plugin.c index ee3f281bc3..ce0860e4c9 100644 --- a/src/plugins/trash/trash-plugin.c +++ b/src/plugins/trash/trash-plugin.c @@ -2,6 +2,7 @@ #include "lib.h" #include "array.h" +#include "unichar.h" #include "istream.h" #include "mail-namespace.h" #include "mail-search-build.h" @@ -273,6 +274,11 @@ static int read_configuration(struct mail_user *user, const char *path) ret = -1; } + if (!uni_utf8_str_is_valid(trash->name)) { + i_error("trash: Mailbox name not UTF-8: %s", + trash->name); + ret = -1; + } if (!trash_find_storage(user, trash)) { i_error("trash: Namespace not found for mailbox '%s'", trash->name); diff --git a/src/plugins/virtual/virtual-config.c b/src/plugins/virtual/virtual-config.c index 932958a0ba..99dab23ff5 100644 --- a/src/plugins/virtual/virtual-config.c +++ b/src/plugins/virtual/virtual-config.c @@ -5,6 +5,7 @@ #include "crc32.h" #include "istream.h" #include "str.h" +#include "unichar.h" #include "imap-parser.h" #include "imap-match.h" #include "mail-namespace.h" @@ -136,6 +137,11 @@ virtual_config_parse_line(struct virtual_parse_context *ctx, const char *line, bbox->ns = strcasecmp(line, "INBOX") == 0 ? mail_namespace_find_inbox(user->namespaces) : mail_namespace_find(user->namespaces, line); + if (!uni_utf8_str_is_valid(bbox->name)) { + *error_r = t_strdup_printf("Mailbox name not UTF-8: %s", + bbox->name); + return -1; + } if (bbox->ns == NULL) { *error_r = t_strdup_printf("Namespace not found for %s", bbox->name);