From: Timo Sirainen Date: Mon, 9 Aug 2010 15:58:33 +0000 (+0100) Subject: listescape: Fixed listing for namespaces whose prefixes had escapeable chars. X-Git-Tag: 2.0.rc5~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=68329839ae2470163a0b841f9221d54d2163914b;p=thirdparty%2Fdovecot%2Fcore.git listescape: Fixed listing for namespaces whose prefixes had escapeable chars. Based on patch by Samuel Kvasnica --- diff --git a/src/plugins/listescape/listescape-plugin.c b/src/plugins/listescape/listescape-plugin.c index ae6a88f413..5fbeca4a4a 100644 --- a/src/plugins/listescape/listescape-plugin.c +++ b/src/plugins/listescape/listescape-plugin.c @@ -108,6 +108,51 @@ static void list_unescape_str(struct listescape_mailbox_list *mlist, } } +static struct mail_namespace * +listescape_find_orig_ns(struct mail_namespace *parent_ns, const char *name) +{ + struct mail_namespace *ns, *best = NULL; + + for (ns = parent_ns->user->namespaces; ns != NULL; ns = ns->next) { + if ((ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) != 0) + continue; + + if (strncmp(ns->prefix, parent_ns->prefix, + parent_ns->prefix_len) == 0 && + strncmp(ns->prefix + parent_ns->prefix_len, name, + ns->prefix_len) == 0) { + if (best == NULL || ns->prefix_len > best->prefix_len) + best = ns; + } + } + return best != NULL ? best : parent_ns; +} + +static const char *const * +iter_escape_patterns(struct mailbox_list *list, + const char *const *patterns, + enum mailbox_list_iter_flags flags) +{ + struct mail_namespace *orig_ns; + const char **escaped_patterns; + unsigned int i; + + escaped_patterns = t_new(const char *, str_array_length(patterns) + 1); + for (i = 0; patterns[i] != NULL; i++) { + if ((flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0) { + /* we may be listing subscriptions for other namespaces + prefixes. don't escape characters in the namespace + prefixes. */ + orig_ns = listescape_find_orig_ns(list->ns, + patterns[i]); + } else { + orig_ns = list->ns; + } + escaped_patterns[i] = list_escape(orig_ns, patterns[i], TRUE); + } + return escaped_patterns; +} + static struct mailbox_list_iterate_context * listescape_mailbox_list_iter_init(struct mailbox_list *list, const char *const *patterns, @@ -116,21 +161,12 @@ listescape_mailbox_list_iter_init(struct mailbox_list *list, struct listescape_mailbox_list *mlist = LIST_ESCAPE_LIST_CONTEXT(list); struct mailbox_list_iterate_context *ctx; struct listescape_mailbox_list_iter *liter; - const char **escaped_patterns; - unsigned int i; /* this is kind of kludgy. In ACL code we want to convert patterns, in maildir renaming code we don't. so for now just use the _RAW_LIST flag.. */ - if ((flags & MAILBOX_LIST_ITER_RAW_LIST) == 0) { - escaped_patterns = t_new(const char *, - str_array_length(patterns) + 1); - for (i = 0; patterns[i] != NULL; i++) { - escaped_patterns[i] = - list_escape(list->ns, patterns[i], TRUE); - } - patterns = escaped_patterns; - } + if ((flags & MAILBOX_LIST_ITER_RAW_LIST) == 0) + patterns = iter_escape_patterns(list, patterns, flags); /* Listing breaks if ns->real_sep isn't correct, but with everything else we need real_sep == virtual_sep. maybe some day lib-storage @@ -146,26 +182,6 @@ listescape_mailbox_list_iter_init(struct mailbox_list *list, return ctx; } -static struct mail_namespace * -listescape_find_orig_ns(struct mail_namespace *parent_ns, const char *name) -{ - struct mail_namespace *ns, *best = NULL; - - for (ns = parent_ns->user->namespaces; ns != NULL; ns = ns->next) { - if ((ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) != 0) - continue; - - if (strncmp(ns->prefix, parent_ns->prefix, - parent_ns->prefix_len) == 0 && - strncmp(ns->prefix + parent_ns->prefix_len, name, - ns->prefix_len) == 0) { - if (best == NULL || ns->prefix_len > best->prefix_len) - best = ns; - } - } - return best != NULL ? best : parent_ns; -} - static struct listescape_mailbox_list_iter * listescape_mailbox_list_iter_find(struct listescape_mailbox_list *mlist, struct mailbox_list_iterate_context *ctx)