]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Use escaped name length to calculate truncation margin
authorMarkus Valentin <markus.valentin@open-xchange.com>
Mon, 12 Jul 2021 12:26:38 +0000 (14:26 +0200)
committerMarkus Valentin <markus.valentin@open-xchange.com>
Wed, 14 Jul 2021 12:41:15 +0000 (14:41 +0200)
This fixes corruption of mailbox names when the storage_name_escape_char
has been part of the parent folder name.

Broken by 5dd81d83d8d9120ed2a74d5bd2aa62622885b49c

src/lib-storage/list/mailbox-list-index-iter.c

index 8806651a4a61f7a438c3b604e16cbe280dbaf1af..def8f3c598f59d8ed35336f2f24b04ee9103d010 100644 (file)
@@ -66,6 +66,19 @@ mailbox_list_index_iter_init(struct mailbox_list *list,
        return &ctx->ctx;
 }
 
+static void
+mailbox_list_get_escaped_mailbox_name(struct mailbox_list *list,
+                                     const char *raw_name,
+                                     string_t *escaped_name)
+{
+       const char escape_chars[] = {
+               list->set.storage_name_escape_char,
+               mailbox_list_get_hierarchy_sep(list),
+               '\0'
+       };
+       mailbox_list_name_escape(raw_name, escape_chars, escaped_name);
+}
+
 static void
 mailbox_list_index_update_info(struct mailbox_list_index_iterate_context *ctx)
 {
@@ -82,12 +95,8 @@ mailbox_list_index_update_info(struct mailbox_list_index_iterate_context *ctx)
                str_append_c(ctx->path,
                             mailbox_list_get_hierarchy_sep(ctx->ctx.list));
        }
-       char escape_chars[] = {
-               ctx->ctx.list->set.storage_name_escape_char,
-               mailbox_list_get_hierarchy_sep(ctx->ctx.list),
-               '\0'
-       };
-       mailbox_list_name_escape(node->raw_name, escape_chars, ctx->path);
+       mailbox_list_get_escaped_mailbox_name(ctx->ctx.list, node->raw_name,
+                                             ctx->path);
 
        ctx->info.vname = mailbox_list_get_vname(ctx->ctx.list, str_c(ctx->path));
        ctx->info.flags = node->children != NULL ?
@@ -152,7 +161,16 @@ mailbox_list_index_update_next(struct mailbox_list_index_iterate_context *ctx,
                while (node->next == NULL) {
                        node = node->parent;
                        if (node != NULL) {
-                               ctx->parent_len -= strlen(node->raw_name);
+                               /* The storage name kept in the iteration context
+                                  is escaped. To calculate the right truncation
+                                  margin, the length of the name must be
+                                  calculated from the escaped storage name and
+                                  not from node->raw_name. */
+                               string_t *escaped_name = t_str_new(64);
+                               mailbox_list_get_escaped_mailbox_name(ctx->ctx.list,
+                                                                     node->raw_name,
+                                                                     escaped_name);
+                               ctx->parent_len -= str_len(escaped_name);
                                if (node->parent != NULL)
                                        ctx->parent_len--;
                        }