[evolution-data-server] I#116 - [IMAPx] Correct handling of mailbox names (with RFC 6855 extension)



commit b478afa29058d758733db8f3c530bc17b7bb3bcd
Author: Milan Crha <mcrha redhat com>
Date:   Mon May 13 14:07:35 2019 +0200

    I#116 - [IMAPx] Correct handling of mailbox names (with RFC 6855 extension)
    
    Closes https://gitlab.gnome.org/GNOME/evolution-data-server/issues/116

 src/camel/providers/imapx/camel-imapx-folder.c     |  7 +-----
 .../providers/imapx/camel-imapx-input-stream.c     | 29 ++++++++++++++++++++++
 .../providers/imapx/camel-imapx-input-stream.h     |  5 ++++
 src/camel/providers/imapx/camel-imapx-server.c     | 27 +++++++++++---------
 src/camel/providers/imapx/camel-imapx-store.c      |  5 +---
 src/camel/providers/imapx/camel-imapx-utils.c      | 10 ++++++--
 6 files changed, 59 insertions(+), 24 deletions(-)
---
diff --git a/src/camel/providers/imapx/camel-imapx-folder.c b/src/camel/providers/imapx/camel-imapx-folder.c
index 95a5811ff..055eb4a4c 100644
--- a/src/camel/providers/imapx/camel-imapx-folder.c
+++ b/src/camel/providers/imapx/camel-imapx-folder.c
@@ -1408,7 +1408,6 @@ camel_imapx_folder_list_mailbox (CamelIMAPXFolder *folder,
        CamelIMAPXStoreInfo *imapx_store_info;
        gchar *folder_path = NULL;
        gchar *mailbox_name = NULL;
-       gchar *pattern;
        gboolean success;
 
        g_return_val_if_fail (CAMEL_IS_IMAPX_FOLDER (folder), FALSE);
@@ -1449,13 +1448,9 @@ camel_imapx_folder_list_mailbox (CamelIMAPXFolder *folder,
        /* Last resort is to issue a LIST command.  Maintainer should
         * monitor IMAP logs to make sure this is rarely if ever used. */
 
-       pattern = camel_utf8_utf7 (mailbox_name);
-
        /* This creates a mailbox instance from the LIST response. */
        conn_man = camel_imapx_store_get_conn_manager (imapx_store);
-       success = camel_imapx_conn_manager_list_sync (conn_man, pattern, 0, cancellable, error);
-
-       g_free (pattern);
+       success = camel_imapx_conn_manager_list_sync (conn_man, mailbox_name, 0, cancellable, error);
 
        if (!success)
                goto exit;
diff --git a/src/camel/providers/imapx/camel-imapx-input-stream.c 
b/src/camel/providers/imapx/camel-imapx-input-stream.c
index f47b08f7d..bb55d62e8 100644
--- a/src/camel/providers/imapx/camel-imapx-input-stream.c
+++ b/src/camel/providers/imapx/camel-imapx-input-stream.c
@@ -46,6 +46,8 @@ struct _CamelIMAPXInputStreamPrivate {
 
        guchar *tokenbuf;
        guint bufsize;
+
+       gboolean utf8_accept;
 };
 
 /* Forward Declarations */
@@ -263,6 +265,7 @@ camel_imapx_input_stream_init (CamelIMAPXInputStream *is)
        is->priv->buf = g_malloc (is->priv->bufsize + 1);
        is->priv->ptr = is->priv->end = is->priv->buf;
        is->priv->tokenbuf = g_malloc (is->priv->bufsize + 1);
+       is->priv->utf8_accept = FALSE;
 }
 
 static void
@@ -329,6 +332,32 @@ camel_imapx_input_stream_buffered (CamelIMAPXInputStream *is)
        return is->priv->end - is->priv->ptr;
 }
 
+/*
+ * Returns whether the stream has enabled RFC 6855 extension,
+ * where strings like mailbox names are not encoded in UTF-7,
+ * but they are provided in UTF-8 directly.
+ */
+gboolean
+camel_imapx_input_stream_get_utf8_accept (CamelIMAPXInputStream *is)
+{
+       g_return_val_if_fail (CAMEL_IS_IMAPX_INPUT_STREAM (is), FALSE);
+
+       return is->priv->utf8_accept;
+}
+
+/*
+ * Sets whether the stream has enabled RFC 6855 extension. The default
+ * is FALSE.
+ */
+void
+camel_imapx_input_stream_set_utf8_accept (CamelIMAPXInputStream *is,
+                                         gboolean utf8_accept)
+{
+       g_return_if_fail (CAMEL_IS_IMAPX_INPUT_STREAM (is));
+
+       is->priv->utf8_accept = utf8_accept;
+}
+
 /* FIXME: these should probably handle it themselves,
  * and get rid of the token interface? */
 gboolean
diff --git a/src/camel/providers/imapx/camel-imapx-input-stream.h 
b/src/camel/providers/imapx/camel-imapx-input-stream.h
index 7d60c5722..88b5a997c 100644
--- a/src/camel/providers/imapx/camel-imapx-input-stream.h
+++ b/src/camel/providers/imapx/camel-imapx-input-stream.h
@@ -79,6 +79,11 @@ GType                camel_imapx_input_stream_get_type
 GInputStream * camel_imapx_input_stream_new    (GInputStream *base_stream);
 gint           camel_imapx_input_stream_buffered
                                                (CamelIMAPXInputStream *is);
+gboolean       camel_imapx_input_stream_get_utf8_accept
+                                               (CamelIMAPXInputStream *is);
+void           camel_imapx_input_stream_set_utf8_accept
+                                               (CamelIMAPXInputStream *is,
+                                                gboolean utf8_accept);
 
 camel_imapx_token_t
                camel_imapx_input_stream_token  (CamelIMAPXInputStream *is,
diff --git a/src/camel/providers/imapx/camel-imapx-server.c b/src/camel/providers/imapx/camel-imapx-server.c
index 20f09aba2..b33a039df 100644
--- a/src/camel/providers/imapx/camel-imapx-server.c
+++ b/src/camel/providers/imapx/camel-imapx-server.c
@@ -3408,6 +3408,9 @@ preauthed:
                g_mutex_lock (&is->priv->stream_lock);
 
                is->priv->utf8_accept = TRUE;
+
+               if (CAMEL_IS_IMAPX_INPUT_STREAM (is->priv->input_stream))
+                       camel_imapx_input_stream_set_utf8_accept (CAMEL_IMAPX_INPUT_STREAM 
(is->priv->input_stream), TRUE);
        }
 
        if (CAMEL_IMAPX_HAVE_CAPABILITY (is->priv->cinfo, NAMESPACE)) {
@@ -6423,29 +6426,33 @@ camel_imapx_server_expunge_sync (CamelIMAPXServer *is,
 
 gboolean
 camel_imapx_server_list_sync (CamelIMAPXServer *is,
-                             const gchar *pattern,
+                             const gchar *in_pattern,
                              CamelStoreGetFolderInfoFlags flags,
                              GCancellable *cancellable,
                              GError **error)
 {
        CamelIMAPXCommand *ic;
+       gchar *utf7_pattern = NULL;
        gboolean success;
 
        g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
-       g_return_val_if_fail (pattern != NULL, FALSE);
+       g_return_val_if_fail (in_pattern != NULL, FALSE);
 
        g_warn_if_fail (is->priv->list_responses_hash == NULL);
        g_warn_if_fail (is->priv->list_responses == NULL);
        g_warn_if_fail (is->priv->lsub_responses == NULL);
 
+       if (!camel_imapx_server_get_utf8_accept (is))
+               utf7_pattern = camel_utf8_utf7 (in_pattern);
+
        if (is->priv->list_return_opts != NULL) {
                ic = camel_imapx_command_new (is, CAMEL_IMAPX_JOB_LIST, "LIST \"\" %s RETURN (%t)",
-                       pattern, is->priv->list_return_opts);
+                       utf7_pattern ? utf7_pattern : in_pattern, is->priv->list_return_opts);
        } else {
                is->priv->list_responses_hash = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
 
                ic = camel_imapx_command_new (is, CAMEL_IMAPX_JOB_LIST, "LIST \"\" %s",
-                       pattern);
+                       utf7_pattern ? utf7_pattern : in_pattern);
        }
 
        success = camel_imapx_server_process_command_sync (is, ic, _("Error fetching folders"), cancellable, 
error);
@@ -6454,13 +6461,15 @@ camel_imapx_server_list_sync (CamelIMAPXServer *is,
 
        if (success && !is->priv->list_return_opts) {
                ic = camel_imapx_command_new (is, CAMEL_IMAPX_JOB_LSUB, "LSUB \"\" %s",
-                       pattern);
+                       utf7_pattern ? utf7_pattern : in_pattern);
 
                success = camel_imapx_server_process_command_sync (is, ic, _("Error fetching subscribed 
folders"), cancellable, error);
 
                camel_imapx_command_unref (ic);
        }
 
+       g_free (utf7_pattern);
+
        if (is->priv->list_responses_hash) {
                CamelIMAPXStore *imapx_store;
                GSList *link;
@@ -6516,17 +6525,11 @@ camel_imapx_server_create_mailbox_sync (CamelIMAPXServer *is,
        camel_imapx_command_unref (ic);
 
        if (success) {
-               gchar *utf7_pattern;
-
-               utf7_pattern = camel_utf8_utf7 (mailbox_name);
-
                /* List the new mailbox so we trigger our untagged
                 * LIST handler.  This simulates being notified of
                 * a newly-created mailbox, so we can just let the
                 * callback functions handle the bookkeeping. */
-               success = camel_imapx_server_list_sync (is, utf7_pattern, 0, cancellable, error);
-
-               g_free (utf7_pattern);
+               success = camel_imapx_server_list_sync (is, mailbox_name, 0, cancellable, error);
        }
 
        return success;
diff --git a/src/camel/providers/imapx/camel-imapx-store.c b/src/camel/providers/imapx/camel-imapx-store.c
index 868f7b7ff..ed3ee353f 100644
--- a/src/camel/providers/imapx/camel-imapx-store.c
+++ b/src/camel/providers/imapx/camel-imapx-store.c
@@ -1605,7 +1605,6 @@ fetch_folder_info_from_folder_path (CamelIMAPXStore *imapx_store,
        CamelIMAPXNamespaceResponse *namespace_response;
        CamelIMAPXNamespace *namespace;
        gchar *mailbox_name;
-       gchar *utf7_mailbox_name;
        gchar *pattern;
        gchar separator;
        gboolean success = FALSE;
@@ -1630,15 +1629,13 @@ fetch_folder_info_from_folder_path (CamelIMAPXStore *imapx_store,
        separator = camel_imapx_namespace_get_separator (namespace);
        mailbox_name = g_strdelimit (g_strdup (folder_path), "/", separator);
 
-       utf7_mailbox_name = camel_utf8_utf7 (mailbox_name);
-       pattern = g_strdup_printf ("%s*", utf7_mailbox_name);
+       pattern = g_strdup_printf ("%s*", mailbox_name);
 
        success = fetch_folder_info_for_pattern (
                conn_man, namespace, pattern, flags,
                folder_info_results, cancellable, error);
 
        g_free (pattern);
-       g_free (utf7_mailbox_name);
        g_free (mailbox_name);
 
 exit:
diff --git a/src/camel/providers/imapx/camel-imapx-utils.c b/src/camel/providers/imapx/camel-imapx-utils.c
index a77a634af..38b8a5b0c 100644
--- a/src/camel/providers/imapx/camel-imapx-utils.c
+++ b/src/camel/providers/imapx/camel-imapx-utils.c
@@ -2963,7 +2963,10 @@ camel_imapx_parse_mailbox (CamelIMAPXInputStream *stream,
        if (!success)
                return NULL;
 
-       mailbox_name = camel_utf7_utf8 ((gchar *) token);
+       if (camel_imapx_input_stream_get_utf8_accept (stream))
+               mailbox_name = g_strdup ((const gchar *) token);
+       else
+               mailbox_name = camel_utf7_utf8 ((const gchar *) token);
 
        camel_imapx_normalize_mailbox (mailbox_name, separator);
 
@@ -3251,7 +3254,10 @@ camel_imapx_parse_quotaroot (CamelIMAPXInputStream *stream,
        if (!success)
                goto fail;
 
-       mailbox_name = camel_utf7_utf8 ((gchar *) token);
+       if (camel_imapx_input_stream_get_utf8_accept (stream))
+               mailbox_name = g_strdup ((const gchar *) token);
+       else
+               mailbox_name = camel_utf7_utf8 ((const gchar *) token);
 
        while (TRUE) {
                /* Peek at the next token, and break


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]