#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"
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;
}
#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"
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);
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;
#include "lib.h"
#include "array.h"
#include "str.h"
+#include "unichar.h"
#include "imap-utf7.h"
#include "mail-namespace.h"
#include "mail-storage.h"
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)
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);
}
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);
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]);
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]);
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]);
"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]);
#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"
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)
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[]);
#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"
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;
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);
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));
/* 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"
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;
/* <mailbox> */
if (!client_read_string_args(cmd, 1, &mailbox))
}
}
+ 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);
#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"
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) {
/* 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;
}
#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"
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;
}
#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"
#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"
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)
*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";
#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"
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;
#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"
}
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 */
#include "ioloop.h"
#include "array.h"
#include "llist.h"
+#include "unichar.h"
#include "istream.h"
#include "eacces-error.h"
#include "mkdir-parents.h"
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;
{
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;
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;
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);
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;
/* 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"
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)
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)
#include "lib.h"
#include "array.h"
+#include "unichar.h"
#include "mail-namespace.h"
#include "mail-search-build.h"
#include "mail-storage-private.h"
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) {
#include "lib.h"
#include "array.h"
+#include "unichar.h"
#include "istream.h"
#include "mail-namespace.h"
#include "mail-search-build.h"
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);
#include "crc32.h"
#include "istream.h"
#include "str.h"
+#include "unichar.h"
#include "imap-parser.h"
#include "imap-match.h"
#include "mail-namespace.h"
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);