[evolution-ews] Bug 738093 - Show folder names with slash properly



commit 2e62109335e85242ab5a1c9d9bbd9a2af1a5884d
Author: Milan Crha <mcrha redhat com>
Date:   Wed Nov 19 19:04:49 2014 +0100

    Bug 738093 - Show folder names with slash properly

 src/camel/camel-ews-store-summary.c                |    2 +-
 src/camel/camel-ews-store.c                        |    8 +-
 src/camel/camel-ews-utils.c                        |   17 ++--
 src/configuration/e-ews-subscribe-foreign-folder.c |    5 +-
 src/server/e-ews-folder.c                          |   83 +++++++++++++++++++-
 src/server/e-ews-folder.h                          |    4 +
 6 files changed, 104 insertions(+), 15 deletions(-)
---
diff --git a/src/camel/camel-ews-store-summary.c b/src/camel/camel-ews-store-summary.c
index f5a999a..413a40d 100644
--- a/src/camel/camel-ews-store-summary.c
+++ b/src/camel/camel-ews-store-summary.c
@@ -14,7 +14,7 @@
 #define S_UNLOCK(x) (g_rec_mutex_unlock(&(x)->priv->s_lock))
 
 #define STORE_GROUP_NAME "##storepriv"
-#define CURRENT_SUMMARY_VERSION 1
+#define CURRENT_SUMMARY_VERSION 2
 
 struct _CamelEwsStoreSummaryPrivate {
        GKeyFile *key_file;
diff --git a/src/camel/camel-ews-store.c b/src/camel/camel-ews-store.c
index 3029665..ad82405 100644
--- a/src/camel/camel-ews-store.c
+++ b/src/camel/camel-ews-store.c
@@ -1982,7 +1982,7 @@ get_public_folder_full_name (EEwsFolder *folder,
        g_return_val_if_fail (folder != NULL, NULL);
        g_return_val_if_fail (folders_by_id != NULL, NULL);
 
-       full_name = g_string_new (e_ews_folder_get_name (folder));
+       full_name = g_string_new (e_ews_folder_get_escaped_name (folder));
        while (folder) {
                parent_fid = e_ews_folder_get_parent_id (folder);
                if (!parent_fid || !parent_fid->id)
@@ -1991,7 +1991,7 @@ get_public_folder_full_name (EEwsFolder *folder,
                folder = g_hash_table_lookup (folders_by_id, parent_fid->id);
                if (folder) {
                        g_string_prepend (full_name, "/");
-                       g_string_prepend (full_name, e_ews_folder_get_name (folder));
+                       g_string_prepend (full_name, e_ews_folder_get_escaped_name (folder));
                }
        }
 
@@ -3248,10 +3248,10 @@ ews_store_subscribe_folder_sync (CamelSubscribable *subscribable,
 
                g_return_val_if_fail (parent_name != NULL, FALSE);
 
-               tmp = g_strconcat (parent_name, "/", e_ews_folder_get_name (folder), NULL);
+               tmp = g_strconcat (parent_name, "/", e_ews_folder_get_escaped_name (folder), NULL);
                g_free (parent_name);
        } else {
-               tmp = g_strconcat (EWS_PUBLIC_FOLDER_ROOT_DISPLAY_NAME, "/", e_ews_folder_get_name (folder), 
NULL);
+               tmp = g_strconcat (EWS_PUBLIC_FOLDER_ROOT_DISPLAY_NAME, "/", e_ews_folder_get_escaped_name 
(folder), NULL);
        }
 
        if (e_ews_folder_get_folder_type (folder) != E_EWS_FOLDER_TYPE_MAILBOX) {
diff --git a/src/camel/camel-ews-utils.c b/src/camel/camel-ews-utils.c
index c6996fd..8f3d7e1 100644
--- a/src/camel/camel-ews-utils.c
+++ b/src/camel/camel-ews-utils.c
@@ -48,6 +48,7 @@ camel_ews_utils_build_folder_info (CamelEwsStore *store,
 {
        CamelEwsStoreSummary *ews_summary = store->summary;
        CamelFolderInfo *fi;
+       gchar *folder_name;
 
        fi = camel_folder_info_new ();
        fi->full_name = camel_ews_store_summary_get_folder_full_name (
@@ -60,14 +61,14 @@ camel_ews_utils_build_folder_info (CamelEwsStore *store,
                return NULL;
        }
 
-       fi->display_name = camel_ews_store_summary_get_folder_name (
-               ews_summary, fid, NULL);
-       fi->flags = camel_ews_store_summary_get_folder_flags (
-               ews_summary, fid, NULL);
-       fi->unread = camel_ews_store_summary_get_folder_unread (
-               ews_summary, fid, NULL);
-       fi->total = camel_ews_store_summary_get_folder_total (
-               ews_summary, fid, NULL);
+       folder_name = camel_ews_store_summary_get_folder_name (ews_summary, fid, NULL);
+
+       fi->display_name = e_ews_folder_utils_unescape_name (folder_name);
+       fi->flags = camel_ews_store_summary_get_folder_flags (ews_summary, fid, NULL);
+       fi->unread = camel_ews_store_summary_get_folder_unread (ews_summary, fid, NULL);
+       fi->total = camel_ews_store_summary_get_folder_total (ews_summary, fid, NULL);
+
+       g_free (folder_name);
 
        if (!(fi->flags & CAMEL_FOLDER_TYPE_MASK)) {
                switch (camel_ews_store_summary_get_folder_type (ews_summary, fid, NULL)) {
diff --git a/src/configuration/e-ews-subscribe-foreign-folder.c 
b/src/configuration/e-ews-subscribe-foreign-folder.c
index 2f6fba8..feeea71 100644
--- a/src/configuration/e-ews-subscribe-foreign-folder.c
+++ b/src/configuration/e-ews-subscribe-foreign-folder.c
@@ -124,8 +124,11 @@ add_foreign_folder_to_camel (CamelEwsStore *ews_store,
                        CAMEL_FOLDER_SUBSCRIBED, e_ews_folder_get_total_count (folder), TRUE, FALSE);
        } else {
                const gchar *displayname;
+               gchar *escaped_name;
 
-               fullname = g_strdup_printf ("%s/%s/%s", EWS_FOREIGN_FOLDER_ROOT_DISPLAY_NAME, mailbox, 
display_foldername);
+               escaped_name = e_ews_folder_utils_escape_name (display_foldername);
+               fullname = g_strdup_printf ("%s/%s/%s", EWS_FOREIGN_FOLDER_ROOT_DISPLAY_NAME, mailbox, 
escaped_name);
+               g_free (escaped_name);
 
                /* make sure the path is unique */
                camel_ews_store_ensure_unique_path (ews_store, &fullname);
diff --git a/src/server/e-ews-folder.c b/src/server/e-ews-folder.c
index b4960c4..3a7e42c 100644
--- a/src/server/e-ews-folder.c
+++ b/src/server/e-ews-folder.c
@@ -38,6 +38,7 @@ G_DEFINE_TYPE (EEwsFolder, e_ews_folder, G_TYPE_OBJECT)
 struct _EEwsFolderPrivate {
        GError *error;
        gchar *name;
+       gchar *escaped_name;
        EwsFolderId *fid;
        EwsFolderId *parent_fid;
        EEwsFolderType folder_type;
@@ -75,6 +76,9 @@ e_ews_folder_finalize (GObject *object)
                priv->name = NULL;
        }
 
+       g_free (priv->escaped_name);
+       priv->escaped_name = NULL;
+
        if (priv->fid) {
                g_free (priv->fid->id);
                g_free (priv->fid->change_key);
@@ -184,8 +188,10 @@ e_ews_folder_set_from_soap_parameter (EEwsFolder *folder,
        }
 
        subparam = e_soap_parameter_get_first_child_by_name (node, "DisplayName");
-       if (subparam)
+       if (subparam) {
                priv->name = e_soap_parameter_get_string_value (subparam);
+               priv->escaped_name = e_ews_folder_utils_escape_name (priv->name);
+       }
 
        subparam = e_soap_parameter_get_first_child_by_name (node, "UnreadCount");
        if (subparam)
@@ -381,7 +387,18 @@ e_ews_folder_set_name (EEwsFolder *folder,
        priv = folder->priv;
 
        g_free (priv->name);
+       g_free (priv->escaped_name);
+
        priv->name = g_strdup (new_name);
+       priv->escaped_name = e_ews_folder_utils_escape_name (priv->name);
+}
+
+const gchar *
+e_ews_folder_get_escaped_name (const EEwsFolder *folder)
+{
+       g_return_val_if_fail (E_IS_EWS_FOLDER (folder), NULL);
+
+       return folder->priv->escaped_name;
 }
 
 const EwsFolderId *
@@ -486,6 +503,70 @@ e_ews_folder_set_foreign (EEwsFolder *folder,
        folder->priv->foreign = is_foreign;
 }
 
+/* escapes backslashes with \5C and forward slashes with \2F */
+gchar *
+e_ews_folder_utils_escape_name (const gchar *folder_name)
+{
+       gint ii, jj, count = 0;
+       gchar *res;
+
+       if (!folder_name)
+               return NULL;
+
+       for (ii = 0; folder_name[ii]; ii++) {
+               if (folder_name[ii] == '\\' || folder_name[ii] == '/')
+                       count++;
+       }
+
+       if (!count)
+               return g_strdup (folder_name);
+
+       res = g_malloc0 (sizeof (gchar *) * (1 + ii + (2 * count)));
+       for (ii = 0, jj = 0; folder_name[ii]; ii++, jj++) {
+               if (folder_name[ii] == '\\') {
+                       res[jj] = '\\';
+                       res[jj + 1] = '5';
+                       res[jj + 2] = 'C';
+                       jj += 2;
+               } else if (folder_name[ii] == '/') {
+                       res[jj] = '\\';
+                       res[jj + 1] = '2';
+                       res[jj + 2] = 'F';
+                       jj += 2;
+               } else {
+                       res[jj] = folder_name[ii];
+               }
+       }
+
+       res[jj] = '\0';
+
+       return res;
+}
+
+/* reverses e_ews_folder_utils_escape_name() processing */
+gchar *
+e_ews_folder_utils_unescape_name (const gchar *escaped_folder_name)
+{
+       gchar *res = g_strdup (escaped_folder_name);
+       gint ii, jj;
+
+       if (!res)
+               return res;
+
+       for (ii = 0, jj = 0; res[ii]; ii++, jj++) {
+               if (res[ii] == '\\' && g_ascii_isxdigit (res[ii + 1]) && g_ascii_isxdigit (res[ii + 2])) {
+                       res[jj] = ((g_ascii_xdigit_value (res[ii + 1]) & 0xF) << 4) | (g_ascii_xdigit_value 
(res[ii + 2]) & 0xF);
+                       ii += 2;
+               } else if (ii != jj) {
+                       res[jj] = res[ii];
+               }
+       }
+
+       res[jj] = '\0';
+
+       return res;
+}
+
 gchar *
 e_ews_folder_utils_pick_color_spec (gint move_by,
                                     gboolean around_middle)
diff --git a/src/server/e-ews-folder.h b/src/server/e-ews-folder.h
index 8bf4b41..21e9a58 100644
--- a/src/server/e-ews-folder.h
+++ b/src/server/e-ews-folder.h
@@ -63,6 +63,7 @@ gboolean      e_ews_folder_is_error (EEwsFolder *folder);
 const GError * e_ews_folder_get_error (const EEwsFolder *folder);
 const gchar *  e_ews_folder_get_name (const EEwsFolder *folder);
 void           e_ews_folder_set_name (EEwsFolder *folder, const gchar *new_name);
+const gchar *  e_ews_folder_get_escaped_name (const EEwsFolder *folder);
 void           e_ews_folder_set_parent_id (EEwsFolder *folder, EwsFolderId *fid);
 const EwsFolderId *
                e_ews_folder_get_parent_id (const EEwsFolder *folder);
@@ -87,6 +88,9 @@ gboolean      e_ews_folder_id_is_equal (const EwsFolderId *a,
                                          const EwsFolderId *b,
                                          gboolean check_change_key);
 
+gchar *                e_ews_folder_utils_escape_name                  (const gchar *folder_name);
+gchar *                e_ews_folder_utils_unescape_name                (const gchar *escaped_folder_name);
+
 typedef enum {
        E_EWS_ESOURCE_FLAG_NONE                 = 0,
        E_EWS_ESOURCE_FLAG_INCLUDE_SUBFOLDERS   = 1 << 0,


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