changeset 8450:f532e962f05d HEAD

acl: Don't break mailbox visibility checks if the name has "*" characters.
author Timo Sirainen <tss@iki.fi>
date Wed, 19 Nov 2008 19:10:26 +0200
parents 9dbb98d029e7
children e14aabe52d8e
files src/plugins/acl/acl-mailbox-list.c
diffstat 1 files changed, 24 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugins/acl/acl-mailbox-list.c	Wed Nov 19 19:04:55 2008 +0200
+++ b/src/plugins/acl/acl-mailbox-list.c	Wed Nov 19 19:10:26 2008 +0200
@@ -217,8 +217,10 @@
 	struct mailbox_list_iterate_context *iter;
 	const struct mailbox_info *info;
 	enum mailbox_list_iter_flags flags;
-	const char *pattern;
-	bool ret = FALSE;
+	string_t *pattern;
+	const char *prefix;
+	unsigned int i, prefix_len;
+	bool stars = FALSE, ret = FALSE;
 
 	/* do we have child mailboxes with LOOKUP right that don't match
 	   the list pattern? */
@@ -234,10 +236,26 @@
 			return FALSE;
 	}
 
-	pattern = t_strdup_printf("%s%c*", ctx->info.name, ctx->sep);
+	/* if mailbox name has '*' characters in it, they'll conflict with the
+	   LIST wildcard. replace then with '%' and verify later that all
+	   results have the correct prefix. */
+	pattern = t_str_new(128);
+	for (i = 0; ctx->info.name[i] != '\0'; i++) {
+		if (ctx->info.name[i] != '*')
+			str_append_c(pattern, ctx->info.name[i]);
+		else {
+			stars = TRUE;
+			str_append_c(pattern, '%');
+		}
+	}
+	str_append_c(pattern, ctx->sep);
+	str_append_c(pattern, '*');
+	prefix = str_c(pattern);
+	prefix_len = str_len(pattern) - 1;
+
 	flags = (ctx->ctx.flags & MAILBOX_LIST_ITER_VIRTUAL_NAMES) |
 		MAILBOX_LIST_ITER_RETURN_NO_FLAGS;
-	iter = mailbox_list_iter_init(ctx->ctx.list, pattern, flags);
+	iter = mailbox_list_iter_init(ctx->ctx.list, str_c(pattern), flags);
 	while ((info = mailbox_list_iter_next(iter)) != NULL) {
 		if (imap_match(ctx->glob, info->name) == IMAP_MATCH_YES) {
 			/* at least one child matches also the original list
@@ -245,7 +263,8 @@
 			ret = FALSE;
 			break;
 		}
-		ret = TRUE;
+		if (!stars || strncmp(info->name, prefix, prefix_len) == 0)
+			ret = TRUE;
 	}
 	(void)mailbox_list_iter_deinit(&iter);
 	return ret;