]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
listescape: Fixed listing for namespaces whose prefixes had escapeable chars.
authorTimo Sirainen <tss@iki.fi>
Mon, 9 Aug 2010 15:58:33 +0000 (16:58 +0100)
committerTimo Sirainen <tss@iki.fi>
Mon, 9 Aug 2010 15:58:33 +0000 (16:58 +0100)
Based on patch by Samuel Kvasnica

src/plugins/listescape/listescape-plugin.c

index ae6a88f4139f9be0fe1fef9c86d033ba6930c440..5fbeca4a4ad313ac7b38debec3dea0cb33dbbf1d 100644 (file)
@@ -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)