]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imapc: Fixed escaping/unescaping mailbox names.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 14 Jan 2016 16:50:23 +0000 (18:50 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 14 Jan 2016 16:50:23 +0000 (18:50 +0200)
This fixes accessing mailbox names with '%' (the escape_char). It also fixes
local namespace separator being different from the remote separator.

src/lib-storage/index/imapc/imapc-list.c
src/lib-storage/index/imapc/imapc-list.h
src/lib-storage/index/imapc/imapc-save.c
src/lib-storage/index/imapc/imapc-storage.c
src/lib-storage/index/imapc/imapc-storage.h

index ef2699c77d4894b9296af6d6710875ad8a292359..349b7111e9963beb7e8e21bbf9fe2c88775ee146 100644 (file)
@@ -153,6 +153,28 @@ imap_list_flag_parse(const char *str, enum mailbox_info_flags *flag_r)
        return FALSE;
 }
 
+static const char *
+imapc_list_to_vname(struct imapc_mailbox_list *list, const char *imapc_name)
+{
+       const char *list_name;
+
+       /* typically mailbox_list_escape_name() is used to escape vname into
+          a list name. but we want to convert remote IMAP name to a list name,
+          so we need to use the remote IMAP separator. */
+       list_name = mailbox_list_escape_name_params(imapc_name, "", list->root_sep,
+               mailbox_list_get_hierarchy_sep(&list->list),
+               list->list.set.escape_char, "");
+       /* list_name is now valid, so we can convert it to vname */
+       return mailbox_list_get_vname(&list->list, list_name);
+}
+
+const char *imapc_list_to_remote(struct imapc_mailbox_list *list, const char *name)
+{
+       return mailbox_list_unescape_name_params(name, "", list->root_sep,
+                               mailbox_list_get_hierarchy_sep(&list->list),
+                               list->list.set.escape_char);
+}
+
 static struct mailbox_node *
 imapc_list_update_tree(struct imapc_mailbox_list *list,
                       struct mailbox_tree_context *tree,
@@ -175,10 +197,8 @@ imapc_list_update_tree(struct imapc_mailbox_list *list,
                flags++;
        }
 
-       name = mailbox_list_escape_name(&list->list, name);
        T_BEGIN {
-               const char *vname =
-                       mailbox_list_get_vname(&list->list, name);
+               const char *vname = imapc_list_to_vname(list, name);
 
                if ((info_flags & MAILBOX_NONEXISTENT) != 0)
                        node = mailbox_tree_lookup(tree, vname);
index 85af9671ffb71acdd070346309d77a71d1e7f6f6..9991442557f7aec946dcab103eef98d4bbf6a365 100644 (file)
@@ -13,6 +13,7 @@ struct imapc_mailbox_list {
        struct imapc_storage_client *client;
        struct mailbox_list *index_list;
 
+       /* mailboxes are stored as vnames */
        struct mailbox_tree_context *mailboxes, *tmp_subscriptions;
        char root_sep;
        time_t last_refreshed_mailboxes;
@@ -34,5 +35,6 @@ struct imapc_mailbox_list {
 int imapc_list_get_mailbox_flags(struct mailbox_list *list, const char *name,
                                 enum mailbox_info_flags *flags_r);
 int imapc_list_try_get_root_sep(struct imapc_mailbox_list *list, char *sep_r);
+const char *imapc_list_to_remote(struct imapc_mailbox_list *list, const char *name);
 
 #endif
index ee67762d38ecddf2e3610d1bf1509d3784c82fe0..b618dad5371d3dd4e014381fc7cec3bbd1d7de60 100644 (file)
@@ -246,7 +246,7 @@ static int imapc_save_append(struct imapc_save_context *ctx)
        cmd = imapc_client_cmd(ctx->mbox->storage->client->client,
                               imapc_save_callback, &sctx);
        imapc_command_sendf(cmd, "APPEND %s%1s%1s %p",
-               mailbox_list_unescape_name(ctx->mbox->box.list, ctx->mbox->box.name),
+               imapc_mailbox_get_remote_name(ctx->mbox),
                flags, internaldate, input);
        i_stream_unref(&input);
        while (sctx.ret == -2)
index edcf75671c7fbf5dfdd569a08f226f21179c4252..00ccb4047843b53900668677457103fe1cb84959 100644 (file)
@@ -414,6 +414,14 @@ imapc_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
        return &mbox->box;
 }
 
+const char *imapc_mailbox_get_remote_name(struct imapc_mailbox *mbox)
+{
+       if (strcmp(mbox->box.list->name, MAILBOX_LIST_NAME_IMAPC) != 0)
+               return mbox->box.name;
+       return imapc_list_to_remote((struct imapc_mailbox_list *)mbox->box.list,
+                                   mbox->box.name);
+}
+
 static int
 imapc_mailbox_exists(struct mailbox *box, bool auto_boxes ATTR_UNUSED,
                     enum mailbox_existence *existence_r)
@@ -473,10 +481,10 @@ static void imapc_mailbox_reopen(void *context)
        imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_SELECT);
        if (imapc_mailbox_want_examine(mbox)) {
                imapc_command_sendf(cmd, "EXAMINE %s",
-                       mailbox_list_unescape_name(mbox->box.list, mbox->box.name));
+                                   imapc_mailbox_get_remote_name(mbox));
        } else {
                imapc_command_sendf(cmd, "SELECT %s",
-                       mailbox_list_unescape_name(mbox->box.list, mbox->box.name));
+                                   imapc_mailbox_get_remote_name(mbox));
        }
        mbox->storage->reopen_count++;
 
@@ -551,10 +559,10 @@ int imapc_mailbox_select(struct imapc_mailbox *mbox)
        imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_SELECT);
        if (imapc_mailbox_want_examine(mbox)) {
                imapc_command_sendf(cmd, "EXAMINE %s",
-                       mailbox_list_unescape_name(mbox->box.list, mbox->box.name));
+                       imapc_mailbox_get_remote_name(mbox));
        } else {
                imapc_command_sendf(cmd, "SELECT %s",
-                       mailbox_list_unescape_name(mbox->box.list, mbox->box.name));
+                       imapc_mailbox_get_remote_name(mbox));
        }
 
        while (ctx.ret == -2)
index ca91e32bf34358abeb08660df6549389d39e3104..25e398f007a72b7e252663e3c249cd59ed4e38d6 100644 (file)
@@ -179,6 +179,7 @@ int imapc_mailbox_commit_delayed_trans(struct imapc_mailbox *mbox,
 void imapc_mailbox_noop(struct imapc_mailbox *mbox);
 void imapc_mailbox_set_corrupted(struct imapc_mailbox *mbox,
                                 const char *reason, ...) ATTR_FORMAT(2, 3);
+const char *imapc_mailbox_get_remote_name(struct imapc_mailbox *mbox);
 
 void imapc_storage_client_register_untagged(struct imapc_storage_client *client,
                                            const char *name,