]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imap: Produce UTF8 quoted strings when UTF8=ACCEPT is enabled and where possible
authorStephan Bosch <stephan.bosch@open-xchange.com>
Sun, 31 Aug 2025 00:12:52 +0000 (02:12 +0200)
committerStephan Bosch <stephan.bosch@open-xchange.com>
Mon, 26 Jan 2026 01:58:58 +0000 (02:58 +0100)
20 files changed:
src/imap-urlauth/imap-urlauth-worker.c
src/imap/cmd-genurlauth.c
src/imap/cmd-getmetadata.c
src/imap/cmd-id.c
src/imap/cmd-idle.c
src/imap/cmd-list.c
src/imap/cmd-namespace.c
src/imap/cmd-notify.c
src/imap/cmd-urlfetch.c
src/imap/imap-fetch-body.c
src/imap/imap-fetch.c
src/imap/imap-notify.c
src/imap/imap-status.c
src/imap/imap-sync-private.h
src/imap/imap-sync.c
src/imap/imap-sync.h
src/lib-storage/index/index-mail-headers.c
src/lib-storage/index/index-mail.c
src/plugins/imap-acl/imap-acl-plugin.c
src/plugins/imap-quota/imap-quota-plugin.c

index 8891acf21a2c526c6d6e049290c403c5d543695f..17a162cb8c592b0e7a742abf0771ff33e17a2494 100644 (file)
@@ -331,6 +331,8 @@ client_fetch_urlpart(struct client *client, const char *url,
        if ((url_flags & IMAP_URLAUTH_FETCH_FLAG_BINARY) != 0)
                imap_msgpart_url_set_decode_to_binary(client->url);
        if ((url_flags & IMAP_URLAUTH_FETCH_FLAG_BODYPARTSTRUCTURE) != 0) {
+               /* FIXME: Implement UTF-8 support for quoted strings in
+                         generated BODYSTRUCTURE element. */
                ret = imap_msgpart_url_get_bodypartstructure(client->url, 0,
                                                             bpstruct_r, &error);
                if (ret <= 0) {
index 2beb56eb0dda4ae0ebca6608b192081615cb9c57..499a3136b2b9af93e3a1f1d35b01b2242eb74e3e 100644 (file)
@@ -9,6 +9,7 @@
 bool cmd_genurlauth(struct client_command_context *cmd)
 {
        const struct imap_arg *args;
+       enum imap_quote_flags qflags = (cmd->utf8 ? IMAP_QUOTE_FLAG_UTF8 : 0);
        string_t *response;
        int ret;
 
@@ -45,7 +46,7 @@ bool cmd_genurlauth(struct client_command_context *cmd)
                }
 
                str_append_c(response, ' ');
-               imap_append_astring(response, url, 0);
+               imap_append_astring(response, url, qflags);
        }
 
        client_send_line(cmd->client, str_c(response));
index 1f913a4271079d28bcc887e6a2545f31e370bba2..171d6a5e2fb857841b196e97c9dc8ab20457adbc 100644 (file)
@@ -109,6 +109,8 @@ imap_metadata_parse_entry_names(struct imap_getmetadata_context *ctx,
 static string_t *
 metadata_add_entry(struct imap_getmetadata_context *ctx, const char *entry)
 {
+       enum imap_quote_flags qflags = (ctx->cmd->utf8 ?
+                                       IMAP_QUOTE_FLAG_UTF8 : 0);
        string_t *str;
 
        str = t_str_new(64);
@@ -121,7 +123,7 @@ metadata_add_entry(struct imap_getmetadata_context *ctx, const char *entry)
                        /* server metadata reply */
                        str_append(str, "\"\"");
                } else if (ctx->cmd->utf8) {
-                       imap_append_astring(str, mailbox_get_vname(ctx->box), FALSE);
+                       imap_append_astring(str, mailbox_get_vname(ctx->box), qflags);
                } else {
                        if (imap_utf8_to_utf7(mailbox_get_vname(ctx->box), mailbox_mutf7) < 0)
                                i_unreached();
@@ -134,7 +136,7 @@ metadata_add_entry(struct imap_getmetadata_context *ctx, const char *entry)
        } else {
                str_append_c(str, ' ');
        }
-       imap_append_astring(str, entry, 0);
+       imap_append_astring(str, entry, qflags);
        return str;
 }
 
index dbf94238bc121f4ea8045cb5e26e2b6ad46f7ed2..b76310265bf3437a457903ee31ad412bd0d235c8 100644 (file)
@@ -42,6 +42,7 @@ cmd_id_log_params(const struct imap_arg *args, struct event *event,
 bool cmd_id(struct client_command_context *cmd)
 {
        const struct imap_settings *set = cmd->client->set;
+       enum imap_quote_flags qflags = (cmd->utf8 ? IMAP_QUOTE_FLAG_UTF8 : 0);
        const struct imap_arg *args;
 
        if (!client_read_args(cmd, 0, 0, &args))
@@ -63,8 +64,9 @@ bool cmd_id(struct client_command_context *cmd)
                str_free(&log_reply);
        }
 
-       client_send_line(cmd->client, t_strdup_printf(
-               "* ID %s", imap_id_reply_generate(&set->imap_id_send, 0)));
+       client_send_line(cmd->client,
+               t_strdup_printf("* ID %s",
+                       imap_id_reply_generate(&set->imap_id_send, qflags)));
        client_send_tagline(cmd, "OK ID completed.");
        return TRUE;
 }
index 538082f9377f146ef487345a8ed74768472da3e1..36d48b990c54af87aef9f5912989b47c72cf3cab 100644 (file)
@@ -140,7 +140,7 @@ static bool idle_sync_now(struct mailbox *box, struct cmd_idle_context *ctx)
        timeout_remove(&ctx->to_hibernate);
 
        ctx->sync_pending = FALSE;
-       ctx->sync_ctx = imap_sync_init(ctx->client, box, 0, 0);
+       ctx->sync_ctx = imap_sync_init(ctx->client, box, 0, 0, ctx->cmd->utf8);
        return cmd_idle_continue(ctx->cmd);
 }
 
index dc56c5ee39efcdef9638bdc71f33654d9b2f0e3e..fc88083e11469a28a5928f2e48981085e387291e 100644 (file)
@@ -273,6 +273,7 @@ list_send_options(struct cmd_list_context *ctx,
 static bool cmd_list_continue(struct client_command_context *cmd)
 {
         struct cmd_list_context *ctx = cmd->context;
+       enum imap_quote_flags qflags = (cmd->utf8 ? IMAP_QUOTE_FLAG_UTF8 : 0);
        const struct mailbox_info *info;
        enum mailbox_info_flags flags;
        string_t *str, *mutf7_name;
@@ -312,7 +313,7 @@ static bool cmd_list_continue(struct client_command_context *cmd)
                list_reply_append_ns_sep_param(str,
                        mail_namespace_get_sep(info->ns));
                str_append_c(str, ' ');
-               imap_append_astring(str, name, 0);
+               imap_append_astring(str, name, qflags);
                mailbox_childinfo2str(ctx, str, flags);
 
                /* send LIST/LSUB response */
@@ -390,6 +391,7 @@ static void cmd_list_init(struct cmd_list_context *ctx,
 
 static void cmd_list_ref_root(struct client *client, const char *ref, bool utf8)
 {
+       enum imap_quote_flags qflags = (utf8 ? IMAP_QUOTE_FLAG_UTF8 : 0);
        struct mail_namespace *ns;
        const char *ns_prefix;
        char ns_sep;
@@ -417,7 +419,7 @@ static void cmd_list_ref_root(struct client *client, const char *ref, bool utf8)
        str_printfa(str, "%c\" ", ns_sep);
        if (*ns_prefix != '\0') {
                /* non-hidden namespace, use it as the root name */
-               imap_append_astring(str, ns_prefix, 0);
+               imap_append_astring(str, ns_prefix, qflags);
        } else {
                /* Hidden namespace or empty namespace prefix. We could just
                   return an empty root name, but it's safer to emulate what
@@ -427,8 +429,10 @@ static void cmd_list_ref_root(struct client *client, const char *ref, bool utf8)
 
                if (p == NULL)
                        str_append(str, "\"\"");
-               else
-                       imap_append_astring(str, t_strdup_until(ref, p + 1), 0);
+               else {
+                       imap_append_astring(str, t_strdup_until(ref, p + 1),
+                                           qflags);
+               }
        }
        client_send_line(client, str_c(str));
 }
index 18b8d65bff916d13ab372e019ceb8fdd62c8dec9..cda7d8cfc6786b1e76be302bfe393a015a17cc80 100644 (file)
@@ -31,6 +31,7 @@ static void
 list_namespaces(struct mail_namespace *ns, enum mail_namespace_type type,
                string_t *str, bool utf8)
 {
+       enum imap_quote_flags qflags = (utf8 ? IMAP_QUOTE_FLAG_UTF8 : 0);
        ARRAY(struct namespace_order) ns_order;
        struct namespace_order *no;
        unsigned int count = 0;
@@ -72,7 +73,7 @@ list_namespaces(struct mail_namespace *ns, enum mail_namespace_type type,
                        prefix = str_c(mutf7_prefix);
                }
 
-               imap_append_string(str, prefix, 0);
+               imap_append_string(str, prefix, qflags);
                str_append(str, " \"");
                if (ns_sep == '\\')
                        str_append_c(str, '\\');
index 47cc979890773b45dd5e010d391aad2b8132a005..fa4bab6c993b59928ed027f325eeeb70c1bcf30f 100644 (file)
@@ -403,6 +403,8 @@ cmd_notify_set(struct imap_notify_context *ctx, const struct imap_arg *args)
 static void
 imap_notify_box_list_noperm(struct client *client, struct mailbox *box)
 {
+       bool utf8 = client_has_enabled(client, imap_feature_utf8accept);
+       enum imap_quote_flags qflags = (utf8 ? IMAP_QUOTE_FLAG_UTF8 : 0);
        string_t *str = t_str_new(128);
        char ns_sep = mail_namespace_get_sep(mailbox_get_namespace(box));
        enum mailbox_info_flags mailbox_flags;
@@ -413,10 +415,12 @@ imap_notify_box_list_noperm(struct client *client, struct mailbox *box)
                mailbox_flags = 0;
 
        vname = mailbox_get_vname(box);
-       string_t *mutf7_name = t_str_new(128);
-       if (imap_utf8_to_utf7(vname, mutf7_name) < 0)
-               i_panic("LIST: Mailbox name not UTF-8: %s", vname);
-       vname = str_c(mutf7_name);
+       if (!utf8) {
+               string_t *mutf7_name = t_str_new(128);
+               if (imap_utf8_to_utf7(vname, mutf7_name) < 0)
+                       i_panic("LIST: Mailbox name not UTF-8: %s", vname);
+               vname = str_c(mutf7_name);
+       }
 
        str_append(str, "* LIST (");
        if (imap_mailbox_flags2str(str, mailbox_flags))
@@ -427,7 +431,7 @@ imap_notify_box_list_noperm(struct client *client, struct mailbox *box)
        str_append_c(str, ns_sep);
        str_append(str, "\" ");
 
-       imap_append_astring(str, vname, 0);
+       imap_append_astring(str, vname, qflags);
        client_send_line(client, str_c(str));
 }
 
index 0cba2f5bf34d2a0a8fc3ffa7c5d50a91fc15d78c..3804fcfc0c4a555b481f1f81954a2fdf6f329bd8 100644 (file)
@@ -286,6 +286,8 @@ cmd_urlfetch_parse_arg(struct client_command_context *cmd,
        const struct imap_arg *params;
        const char *url_text;
 
+       if (cmd->utf8)
+               url_flags |= IMAP_URLAUTH_FETCH_FLAG_UTF8;
        if (imap_arg_get_list(arg, &params))
                url_flags |= IMAP_URLAUTH_FETCH_FLAG_EXTENDED;
        else
index ddc9f3511d155c2ff0acddb05fed20835e57f5e9..c874941f5ffdc197bfe9fa24f2b0f18bde1ffc30 100644 (file)
@@ -247,6 +247,8 @@ body_header_fields_parse(struct imap_fetch_init_context *ctx,
                         struct imap_fetch_body_data *body, const char *prefix,
                         const struct imap_arg *args, unsigned int args_count)
 {
+       enum imap_quote_flags qflags = (ctx->fetch_ctx->utf8 ?
+                                       IMAP_QUOTE_FLAG_UTF8 : 0);
        string_t *str;
        const char *value;
        size_t i;
@@ -271,7 +273,7 @@ body_header_fields_parse(struct imap_fetch_init_context *ctx,
                if (args[i].type == IMAP_ARG_ATOM)
                        str_append(str, value);
                else
-                       imap_append_quoted(str, value, 0);
+                       imap_append_quoted(str, value, qflags);
        }
        str_append_c(str, ')');
        body->section = str_c(str);
@@ -601,6 +603,7 @@ static int ATTR_NULL(3)
 fetch_snippet(struct imap_fetch_context *ctx, struct mail *mail,
              struct imap_fetch_preview_data *preview)
 {
+       enum imap_quote_flags qflags = (ctx->utf8 ? IMAP_QUOTE_FLAG_UTF8 : 0);
        enum mail_lookup_abort temp_lookup_abort = preview->lazy ? MAIL_LOOKUP_ABORT_NOT_IN_CACHE_START_CACHING : mail->lookup_abort;
        enum mail_lookup_abort orig_lookup_abort = mail->lookup_abort;
        const char *resp, *snippet;
@@ -640,7 +643,7 @@ fetch_snippet(struct imap_fetch_context *ctx, struct mail *mail,
        else
                str_append(ctx->state.cur_str, " ");
        if (ret == 0)
-               imap_append_string(ctx->state.cur_str, snippet, 0);
+               imap_append_string(ctx->state.cur_str, snippet, qflags);
        else
                str_append(ctx->state.cur_str, "NIL");
        if (preview->old_standard)
index 0dca6079052f169e09e06ae624e5caebee2b7bc2..5a032a516b5eeab7b8c674632028a32ad9a2627f 100644 (file)
@@ -943,6 +943,7 @@ static bool fetch_guid_init(struct imap_fetch_init_context *ctx)
 static int fetch_x_mailbox(struct imap_fetch_context *ctx, struct mail *mail,
                           void *context ATTR_UNUSED)
 {
+       enum imap_quote_flags qflags = (ctx->utf8 ? IMAP_QUOTE_FLAG_UTF8 : 0);
        const char *name;
 
        if (mail_get_special(mail, MAIL_FETCH_MAILBOX_NAME, &name) < 0) {
@@ -959,7 +960,7 @@ static int fetch_x_mailbox(struct imap_fetch_context *ctx, struct mail *mail,
        }
 
        str_append(ctx->state.cur_str, "X-MAILBOX ");
-       imap_append_astring(ctx->state.cur_str, name, 0);
+       imap_append_astring(ctx->state.cur_str, name, qflags);
        str_append_c(ctx->state.cur_str, ' ');
        return 1;
 }
index e0f4cf8a0b3aca2fc6d74b418d8af4a79bfa2462..a57ecb3d80df0170848051c81cfe6bcef5731e66 100644 (file)
@@ -22,6 +22,8 @@ static int imap_notify_list(struct imap_notify_namespace *notify_ns,
                            enum mailbox_info_flags flags)
 {
        struct client *client = notify_ns->ctx->client;
+       bool utf8 = client_has_enabled(client, imap_feature_utf8accept);
+       enum imap_quote_flags qflags = (utf8 ? IMAP_QUOTE_FLAG_UTF8 : 0);
        string_t *str = t_str_new(128), *mutf7_vname;
        char ns_sep = mail_namespace_get_sep(notify_ns->ns);
        const char *vname, *old_vname;
@@ -35,21 +37,25 @@ static int imap_notify_list(struct imap_notify_namespace *notify_ns,
        str_append(str, "\" ");
 
        vname = rec->vname;
-       mutf7_vname = t_str_new(128);
-       if (imap_utf8_to_utf7(vname, mutf7_vname) < 0)
-               i_panic("Mailbox name not UTF-8: %s", vname);
-       vname = str_c(mutf7_vname);
-       imap_append_astring(str, vname, 0);
+       if (!utf8) {
+               mutf7_vname = t_str_new(128);
+               if (imap_utf8_to_utf7(vname, mutf7_vname) < 0)
+                       i_panic("Mailbox name not UTF-8: %s", vname);
+               vname = str_c(mutf7_vname);
+       }
+       imap_append_astring(str, vname, qflags);
        if (rec->old_vname != NULL) {
                old_vname = rec->old_vname;
-               str_truncate(mutf7_vname, 0);
-               if (imap_utf8_to_utf7(old_vname, mutf7_vname) < 0) {
-                       i_panic("Mailbox name not UTF-8: %s",
-                               old_vname);
+               if (!utf8) {
+                       str_truncate(mutf7_vname, 0);
+                       if (imap_utf8_to_utf7(old_vname, mutf7_vname) < 0) {
+                               i_panic("Mailbox name not UTF-8: %s",
+                                       old_vname);
+                       }
+                       old_vname = str_c(mutf7_vname);
                }
-               old_vname = str_c(mutf7_vname);
                str_append(str, " (\"OLDNAME\" (");
-               imap_append_astring(str, old_vname, 0);
+               imap_append_astring(str, old_vname, qflags);
                str_append(str, "))");
        }
        return client_send_line_next(client, str_c(str));
index 360361ce9b629152b2346e8ae160dc14eb5049fa..2586ce8be5ebfb5290cbd64c7a26354ff2ff18ec 100644 (file)
@@ -132,13 +132,15 @@ int imap_status_send(struct client *client, const char *mailbox_mutf7,
                     const struct imap_status_items *items,
                     const struct imap_status_result *result)
 {
+       bool utf8 = client_has_enabled(client, imap_feature_utf8accept);
+       enum imap_quote_flags qflags = (utf8 ? IMAP_QUOTE_FLAG_UTF8 : 0);
        const struct mailbox_status *status = &result->status;
        string_t *str;
        size_t prefix_len;
 
        str = t_str_new(128);
        str_append(str, "* STATUS ");
-        imap_append_astring(str, mailbox_mutf7, 0);
+        imap_append_astring(str, mailbox_mutf7, qflags);
        str_append(str, " (");
 
        prefix_len = str_len(str);
index b0b1715a09030aa980fbcbe9d258b3641c563304..70ac996af3a69316f1ecc71e5cb7ac1857fed324 100644 (file)
@@ -42,6 +42,7 @@ struct imap_sync_context {
        bool no_newmail:1;
        bool have_new_mails:1;
        bool search_update_notifying:1;
+       bool utf8:1;
 };
 
 #endif
index 8865bba4af325c08102c6f85661f587b388cabcf..b8d80656f8b622eebed38dfcd001a2885bf67be6 100644 (file)
@@ -90,6 +90,7 @@ imap_sync_send_search_update(struct imap_sync_context *ctx,
                             const struct imap_search_update *update,
                             bool removes_only)
 {
+       enum imap_quote_flags qflags = (ctx->utf8 ? IMAP_QUOTE_FLAG_UTF8 : 0);
        string_t *cmd;
        int ret = 1;
 
@@ -113,7 +114,7 @@ imap_sync_send_search_update(struct imap_sync_context *ctx,
 
        cmd = t_str_new(256);
        str_append(cmd, "* ESEARCH (TAG ");
-       imap_append_string(cmd, update->tag, 0);
+       imap_append_string(cmd, update->tag, qflags);
        str_append_c(cmd, ')');
        if (update->return_uids)
                str_append(cmd, " UID");
@@ -168,7 +169,8 @@ imap_sync_send_search_updates(struct imap_sync_context *ctx, bool removes_only)
 
 struct imap_sync_context *
 imap_sync_init(struct client *client, struct mailbox *box,
-              enum imap_sync_flags imap_flags, enum mailbox_sync_flags flags)
+              enum imap_sync_flags imap_flags, enum mailbox_sync_flags flags,
+              bool utf8)
 {
        struct imap_sync_context *ctx;
 
@@ -183,6 +185,7 @@ imap_sync_init(struct client *client, struct mailbox *box,
        ctx->client = client;
        ctx->box = box;
        ctx->imap_flags = imap_flags;
+       ctx->utf8 = utf8;
        i_array_init(&ctx->module_contexts, 5);
 
        /* make sure user can't DoS the system by causing Dovecot to create
@@ -708,7 +711,8 @@ static bool cmd_sync_client(struct client_command_context *sync_cmd)
 
        client->syncing = TRUE;
 
-       ctx = imap_sync_init(client, client->mailbox, imap_flags, flags);
+       ctx = imap_sync_init(client, client->mailbox, imap_flags, flags,
+                            sync_cmd->utf8);
        ctx->no_newmail = no_newmail;
 
        /* handle the syncing using sync_cmd. it doesn't actually matter which
index a1c519872ab52bb75ef53a1332ba1727aa1acaa1..b1e72a893c1d179296cf19cf6ca69673f5da85a6 100644 (file)
@@ -10,7 +10,8 @@ struct client;
 
 struct imap_sync_context *
 imap_sync_init(struct client *client, struct mailbox *box,
-              enum imap_sync_flags imap_flags, enum mailbox_sync_flags flags);
+              enum imap_sync_flags imap_flags, enum mailbox_sync_flags flags,
+              bool utf8);
 int imap_sync_deinit(struct imap_sync_context *ctx,
                     struct client_command_context *sync_cmd);
 int imap_sync_more(struct imap_sync_context *ctx);
index cf16e39b694faf7d68be4954723679e40dc717c6..06d4147509769527771a66d59f816faeab47da18 100644 (file)
@@ -291,6 +291,8 @@ static void index_mail_parse_finish_imap_envelope(struct index_mail *mail)
        string_t *str;
 
        str = str_new(mail->mail.data_pool, 256);
+       /* FIXME: Implement UTF-8 support for quoted strings in generated
+                 ENVELOPE element. */
        imap_envelope_write(mail->data.envelope_data, str, 0);
        mail->data.envelope = str_c(str);
        mail->data.save_envelope = FALSE;
index 214570d34649323b9a794f12109c7b532f97d68f..43b91f28a1cb709dd7b34941ece09518bf430717 100644 (file)
@@ -824,7 +824,9 @@ index_mail_write_bodystructure(struct index_mail *mail, string_t *str,
 {
        const char *error;
 
-       if (imap_bodystructure_write(mail->data.parts, str, extended, FALSE,
+       /* FIXME: Implement UTF-8 support for quoted strings in generated
+                 BODYSTRUCTURE element. */
+       if (imap_bodystructure_write(mail->data.parts, str, extended, 0,
                                     &error) < 0) {
                mail_set_cache_corrupted(&mail->mail.mail,
                        MAIL_FETCH_MESSAGE_PARTS, error);
index e2c0e5f01c07799a73d386b7c0ce76bb0c901856..d24def88ec4cfc821b3e7234079d9dd526de43c0 100644 (file)
@@ -175,8 +175,9 @@ imap_acl_write_rights_list(string_t *dest, const char *const *rights)
 
 static void
 imap_acl_write_right(string_t *dest, string_t *tmp,
-                    const struct acl_rights *right, bool neg)
+                    const struct acl_rights *right, bool neg, bool utf8)
 {
+       enum imap_quote_flags qflags = (utf8 ? IMAP_QUOTE_FLAG_UTF8 : 0);
        const char *const *rights = neg ? right->neg_rights : right->rights;
 
        str_truncate(tmp, 0);
@@ -208,7 +209,7 @@ imap_acl_write_right(string_t *dest, string_t *tmp,
                i_unreached();
        }
 
-       imap_append_astring(dest, str_c(tmp), 0);
+       imap_append_astring(dest, str_c(tmp), qflags);
        str_append_c(dest, ' ');
        imap_acl_write_rights_list(dest, rights);
 }
@@ -252,7 +253,7 @@ have_positive_owner_rights(struct acl_backend *backend,
 static int
 imap_acl_write_aclobj(string_t *dest, struct acl_backend *backend,
                      struct acl_object *aclobj, bool convert_owner,
-                     bool add_default)
+                     bool add_default, bool utf8)
 {
        struct acl_object_list_iter *iter;
        struct acl_rights rights;
@@ -280,7 +281,7 @@ imap_acl_write_aclobj(string_t *dest, struct acl_backend *backend,
                                str_truncate(dest, orig_len);
                                return imap_acl_write_aclobj(dest, backend,
                                                             aclobj, FALSE,
-                                                            add_default);
+                                                            add_default, utf8);
                        }
                        seen_owner = TRUE;
                        if (rights.rights != NULL)
@@ -289,11 +290,11 @@ imap_acl_write_aclobj(string_t *dest, struct acl_backend *backend,
 
                if (rights.rights != NULL) {
                        str_append_c(dest, ' ');
-                       imap_acl_write_right(dest, tmp, &rights, FALSE);
+                       imap_acl_write_right(dest, tmp, &rights, FALSE, utf8);
                }
                if (rights.neg_rights != NULL) {
                        str_append_c(dest, ' ');
-                       imap_acl_write_right(dest, tmp, &rights, TRUE);
+                       imap_acl_write_right(dest, tmp, &rights, TRUE, utf8);
                }
        }
        ret = acl_object_list_deinit(&iter);
@@ -310,7 +311,7 @@ imap_acl_write_aclobj(string_t *dest, struct acl_backend *backend,
                rights.rights = acl_object_get_default_rights(aclobj);
                if (rights.rights != NULL) {
                        str_append_c(dest, ' ');
-                       imap_acl_write_right(dest, tmp, &rights, FALSE);
+                       imap_acl_write_right(dest, tmp, &rights, FALSE, utf8);
                }
        }
        return ret;
@@ -630,6 +631,7 @@ static int
 imap_acl_send_myrights(struct client_command_context *cmd,
                       struct mailbox *box, const char *mutf7_mailbox)
 {
+       enum imap_quote_flags qflags = (cmd->utf8 ? IMAP_QUOTE_FLAG_UTF8 : 0);
        const char *const *rights;
        string_t *str;
 
@@ -644,7 +646,7 @@ imap_acl_send_myrights(struct client_command_context *cmd,
 
        str = t_str_new(128);
        str_append(str, "* MYRIGHTS ");
-       imap_append_astring(str, mutf7_mailbox, 0);
+       imap_append_astring(str, mutf7_mailbox, qflags);
        str_append_c(str, ' ');
        imap_acl_write_rights_list(str, rights);
 
@@ -656,6 +658,7 @@ static void imap_acl_cmd_getacl(struct mailbox *box, struct mail_namespace *ns,
                                const char *mailbox,
                                struct client_command_context *cmd)
 {
+       enum imap_quote_flags qflags = (cmd->utf8 ? IMAP_QUOTE_FLAG_UTF8 : 0);
        struct acl_backend *backend;
        string_t *str;
        int ret;
@@ -667,11 +670,12 @@ static void imap_acl_cmd_getacl(struct mailbox *box, struct mail_namespace *ns,
 
        str = t_str_new(128);
        str_append(str, "* ACL ");
-       imap_append_astring(str, mailbox, 0);
+       imap_append_astring(str, mailbox, qflags);
 
        ret = imap_acl_write_aclobj(str, backend,
                                    acl_mailbox_get_aclobj(box), TRUE,
-                                   ns->type == MAIL_NAMESPACE_TYPE_PRIVATE);
+                                   ns->type == MAIL_NAMESPACE_TYPE_PRIVATE,
+                                   cmd->utf8);
        if (ret > -1) {
                client_send_line(cmd->client, str_c(str));
                client_send_tagline(cmd, "OK Getacl completed.");
@@ -784,6 +788,7 @@ static bool cmd_myrights(struct client_command_context *cmd)
 
 static bool cmd_listrights(struct client_command_context *cmd)
 {
+       enum imap_quote_flags qflags = (cmd->utf8 ? IMAP_QUOTE_FLAG_UTF8 : 0);
        struct mailbox *box;
        struct mail_namespace *ns;
        const char *mailbox, *orig_mailbox, *identifier;
@@ -802,9 +807,9 @@ static bool cmd_listrights(struct client_command_context *cmd)
 
        str = t_str_new(128);
        str_append(str, "* LISTRIGHTS ");
-       imap_append_astring(str, orig_mailbox, 0);
+       imap_append_astring(str, orig_mailbox, qflags);
        str_append_c(str, ' ');
-       imap_append_astring(str, identifier, 0);
+       imap_append_astring(str, identifier, qflags);
        str_append_c(str, ' ');
        str_append(str, "\"\" l r w s t p i e k x a c d");
 
@@ -1065,6 +1070,7 @@ imap_acl_cmd_setacl(struct mailbox *box, struct mail_namespace *ns,
 
 static bool cmd_setacl(struct client_command_context *cmd)
 {
+       enum imap_quote_flags qflags = (cmd->utf8 ? IMAP_QUOTE_FLAG_UTF8 : 0);
        struct mail_namespace *ns;
        struct mailbox *box;
        const char *mailbox, *orig_mailbox, *identifier, *rights;
@@ -1080,7 +1086,7 @@ static bool cmd_setacl(struct client_command_context *cmd)
        }
 
        /* Keep original identifer for proxy_cmd_args */
-       imap_append_astring(proxy_cmd_args, identifier, 0);
+       imap_append_astring(proxy_cmd_args, identifier, qflags);
        str_append_c(proxy_cmd_args, ' ');
        /* Append original rights for proxy_cmd_args */
        imap_append_astring(proxy_cmd_args, rights, 0);
@@ -1139,6 +1145,7 @@ imap_acl_cmd_deleteacl(struct mailbox *box, const char *mailbox,
 
 static bool cmd_deleteacl(struct client_command_context *cmd)
 {
+       enum imap_quote_flags qflags = (cmd->utf8 ? IMAP_QUOTE_FLAG_UTF8 : 0);
        struct mailbox *box;
        struct mail_namespace *ns;
        const char *mailbox, *orig_mailbox, *identifier;
@@ -1158,7 +1165,7 @@ static bool cmd_deleteacl(struct client_command_context *cmd)
                return TRUE;
 
        /* Escaped identifer for proxy_cmd_args */
-       imap_append_astring(proxy_cmd_args, identifier, 0);
+       imap_append_astring(proxy_cmd_args, identifier, qflags);
 
        box = mailbox_alloc(ns->list, mailbox,
                            MAILBOX_FLAG_READONLY | MAILBOX_FLAG_IGNORE_ACLS);
index 9344a4f567986d7e2840fc3b772236e765cf69a6..e9ec624b4b456839bb26b1f0bbff6b6d302efe44 100644 (file)
@@ -34,8 +34,9 @@ imap_quota_root_get_name(struct mail_user *user, struct mail_user *owner,
 
 static int
 quota_reply_write(string_t *str, struct mail_user *user,
-                 struct mail_user *owner, struct quota_root *root)
+                 struct mail_user *owner, struct quota_root *root, bool utf8)
 {
+       enum imap_quote_flags qflags = (utf8 ? IMAP_QUOTE_FLAG_UTF8 : 0);
         const char *name, *const *list, *error;
        unsigned int i;
        uint64_t value, limit;
@@ -44,7 +45,7 @@ quota_reply_write(string_t *str, struct mail_user *user,
 
        str_append(str, "* QUOTA ");
        name = imap_quota_root_get_name(user, owner, root);
-       imap_append_astring(str, name, 0);
+       imap_append_astring(str, name, qflags);
 
        str_append(str, " (");
        prefix_len = str_len(str);
@@ -77,6 +78,7 @@ quota_reply_write(string_t *str, struct mail_user *user,
 static bool cmd_getquotaroot(struct client_command_context *cmd)
 {
        struct client *client = cmd->client;
+       enum imap_quote_flags qflags = (cmd->utf8 ? IMAP_QUOTE_FLAG_UTF8 : 0);
        struct quota_user *quser = QUOTA_USER_CONTEXT(client->user);
        struct mail_namespace *ns;
        struct mailbox *box;
@@ -110,7 +112,7 @@ static bool cmd_getquotaroot(struct client_command_context *cmd)
        quotaroot_reply = t_str_new(128);
        quota_reply = t_str_new(256);
        str_append(quotaroot_reply, "* QUOTAROOT ");
-       imap_append_astring(quotaroot_reply, orig_mailbox, 0);
+       imap_append_astring(quotaroot_reply, orig_mailbox, qflags);
 
        ret = 0;
        iter = quota_root_iter_init(box);
@@ -119,9 +121,10 @@ static bool cmd_getquotaroot(struct client_command_context *cmd)
                        continue;
                str_append_c(quotaroot_reply, ' ');
                name = imap_quota_root_get_name(client->user, ns->owner, root);
-               imap_append_astring(quotaroot_reply, name, 0);
+               imap_append_astring(quotaroot_reply, name, qflags);
 
-               if (quota_reply_write(quota_reply, client->user, ns->owner, root) < 0)
+               if (quota_reply_write(quota_reply, client->user, ns->owner,
+                                     root, cmd->utf8) < 0)
                        ret = -1;
        }
        quota_root_iter_deinit(&iter);
@@ -179,7 +182,8 @@ static bool cmd_getquota(struct client_command_context *cmd)
        }
 
        quota_reply = t_str_new(128);
-       if (quota_reply_write(quota_reply, cmd->client->user, owner, root) < 0)
+       if (quota_reply_write(quota_reply, cmd->client->user, owner,
+                             root, cmd->utf8) < 0)
                client_send_tagline(cmd, "NO Internal quota calculation error.");
        else {
                o_stream_nsend(cmd->client->output, str_data(quota_reply),