changeset 19560:5e6afd3b67b6

imapc: Fixed escaping/unescaping mailbox names. This fixes accessing mailbox names with '%' (the escape_char). It also fixes local namespace separator being different from the remote separator.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 14 Jan 2016 18:50:23 +0200
parents 94c83436a1f4
children bac33082d68a
files 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
diffstat 5 files changed, 39 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/imapc/imapc-list.c	Thu Jan 14 18:47:40 2016 +0200
+++ b/src/lib-storage/index/imapc/imapc-list.c	Thu Jan 14 18:50:23 2016 +0200
@@ -153,6 +153,28 @@
 	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 @@
 		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);
--- a/src/lib-storage/index/imapc/imapc-list.h	Thu Jan 14 18:47:40 2016 +0200
+++ b/src/lib-storage/index/imapc/imapc-list.h	Thu Jan 14 18:50:23 2016 +0200
@@ -13,6 +13,7 @@
 	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 @@
 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
--- a/src/lib-storage/index/imapc/imapc-save.c	Thu Jan 14 18:47:40 2016 +0200
+++ b/src/lib-storage/index/imapc/imapc-save.c	Thu Jan 14 18:50:23 2016 +0200
@@ -246,7 +246,7 @@
 	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)
--- a/src/lib-storage/index/imapc/imapc-storage.c	Thu Jan 14 18:47:40 2016 +0200
+++ b/src/lib-storage/index/imapc/imapc-storage.c	Thu Jan 14 18:50:23 2016 +0200
@@ -414,6 +414,14 @@
 	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 @@
 	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 @@
 	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)
--- a/src/lib-storage/index/imapc/imapc-storage.h	Thu Jan 14 18:47:40 2016 +0200
+++ b/src/lib-storage/index/imapc/imapc-storage.h	Thu Jan 14 18:50:23 2016 +0200
@@ -179,6 +179,7 @@
 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,