From: sergey.kitov Date: Wed, 3 May 2023 11:35:54 +0000 (+0300) Subject: acl: Fix wrong \HasChildren flags for parent mailboxes containing '*' and '%' X-Git-Tag: 2.4.0~2611 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=266baf4b45ccff601bda2f22bcba3f6f0cdc45e7;p=thirdparty%2Fdovecot%2Fcore.git acl: Fix wrong \HasChildren flags for parent mailboxes containing '*' and '%' '*' in mailbox name is replaced with '%' while child mailboxes still have '*' in their path, this results in wrong \HasNoChildren flag. --- diff --git a/src/plugins/acl/acl-mailbox-list.c b/src/plugins/acl/acl-mailbox-list.c index 102d57b27e..f21254f60f 100644 --- a/src/plugins/acl/acl-mailbox-list.c +++ b/src/plugins/acl/acl-mailbox-list.c @@ -285,9 +285,8 @@ iter_mailbox_has_visible_children(struct mailbox_list_iterate_context *_ctx, struct mailbox_list_iterate_context *iter; const struct mailbox_info *info; string_t *pattern; - const char *prefix; size_t i, prefix_len; - bool stars = FALSE, ret = FALSE; + bool wildcards = FALSE, ret = FALSE; /* do we have child mailboxes with LOOKUP right that don't match the list pattern? */ @@ -308,18 +307,21 @@ iter_mailbox_has_visible_children(struct mailbox_list_iterate_context *_ctx, results have the correct prefix. */ pattern = t_str_new(128); for (i = 0; ctx->info.vname[i] != '\0'; i++) { - if (ctx->info.vname[i] != '*') + if (ctx->info.vname[i] != '*' && ctx->info.vname[i] != '%') str_append_c(pattern, ctx->info.vname[i]); else { - stars = TRUE; + wildcards = TRUE; str_append_c(pattern, '%'); } } if (i > 0 && ctx->info.vname[i-1] != ctx->sep) str_append_c(pattern, ctx->sep); str_append_c(pattern, '*'); - prefix = str_c(pattern); prefix_len = str_len(pattern) - 1; + if (prefix_len == 0) { + /* empty mailbox names shouldn't be possible */ + return FALSE; + } iter = mailbox_list_iter_init(_ctx->list, str_c(pattern), (!subscribed ? 0 : @@ -333,7 +335,9 @@ iter_mailbox_has_visible_children(struct mailbox_list_iterate_context *_ctx, ret = FALSE; break; } - if (!stars || strncmp(info->vname, prefix, prefix_len) == 0) + if (!wildcards || + (strncmp(info->vname, ctx->info.vname, prefix_len-1) == 0 && + info->vname[prefix_len-1] == ctx->sep)) ret = TRUE; } (void)mailbox_list_iter_deinit(&iter);