[evolution-ews/gnome-3-8] Bug #704914 - Crash under e_ews_dump_file_attachment_from_soap_parameter()



commit d691d24a50ab0fe1a389604d636d532d262293e9
Author: Milan Crha <mcrha redhat com>
Date:   Mon Jul 29 18:19:17 2013 +0200

    Bug #704914 - Crash under e_ews_dump_file_attachment_from_soap_parameter()
    
    Workaround if save to a cache folder fails, just drop the attachments, if any.
    Respective console (book/cal/mail) contains critical warnings about this situation.

 src/calendar/e-cal-backend-ews.c |    9 ++++-
 src/camel/camel-ews-folder.c     |   10 ++----
 src/camel/camel-ews-store.c      |    2 +-
 src/server/e-ews-connection.c    |    8 +----
 src/server/e-ews-item.c          |   57 ++++++++++++++++++++++++++-----------
 src/server/e-soap-message.c      |    5 +++
 6 files changed, 58 insertions(+), 33 deletions(-)
---
diff --git a/src/calendar/e-cal-backend-ews.c b/src/calendar/e-cal-backend-ews.c
index 36d5ff6..ed53cbd 100644
--- a/src/calendar/e-cal-backend-ews.c
+++ b/src/calendar/e-cal-backend-ews.c
@@ -3202,9 +3202,14 @@ ews_get_attachments (ECalBackendEws *cbews,
 
                for (l = info_attachments; l; l = l->next) {
                        EEwsAttachmentInfo *info = l->data;
-                       const gchar *uri = e_ews_attachment_info_get_uri (info);
 
-                       uris = g_slist_append (uris, g_strdup (uri));
+                       /* ignore non-uri attachments, because it's an exception */
+                       if (e_ews_attachment_info_get_type (info) == E_EWS_ATTACHMENT_INFO_TYPE_URI) {
+                               const gchar *uri = e_ews_attachment_info_get_uri (info);
+
+                               if (uri)
+                                       uris = g_slist_append (uris, g_strdup (uri));
+                       }
                }
 
                e_cal_component_set_attachment_list (comp, uris);
diff --git a/src/camel/camel-ews-folder.c b/src/camel/camel-ews-folder.c
index ae2bf4a..673d50c 100644
--- a/src/camel/camel-ews-folder.c
+++ b/src/camel/camel-ews-folder.c
@@ -294,7 +294,6 @@ ews_update_mgtrequest_mime_calendar_itemid (const gchar *mime_fname,
                icalcomponent *icalcomp, *subcomp;
                icalproperty *icalprop;
                gchar *calstring_new, *dir;
-               const gchar *temp;
                gint fd;
                gboolean success = FALSE;
 
@@ -335,9 +334,8 @@ ews_update_mgtrequest_mime_calendar_itemid (const gchar *mime_fname,
                icalcomponent_free (icalcomp);
                g_object_unref (tmpstream);
 
-               // Create a new file to store updated mimecontent
-               temp = g_strrstr (mime_fname, "/");
-               dir = g_strndup (mime_fname, temp - mime_fname);
+               /* Create a new file to store updated mimecontent */
+               dir = g_path_get_dirname (mime_fname);
                mime_fname_new = g_build_filename ((const gchar *) dir, "XXXXXX", NULL);
                fd = g_mkstemp (mime_fname_new);
                if (fd == -1) {
@@ -399,7 +397,6 @@ camel_ews_folder_get_message (CamelFolder *folder,
        gchar *mime_dir;
        gchar *cache_file;
        gchar *dir;
-       const gchar *temp;
        gboolean res;
        gchar *mime_fname_new = NULL;
        GError *local_error = NULL;
@@ -522,8 +519,7 @@ camel_ews_folder_get_message (CamelFolder *folder,
 
        cache_file = ews_data_cache_get_filename (
                ews_folder->cache, "cur", uid, error);
-       temp = g_strrstr (cache_file, "/");
-       dir = g_strndup (cache_file, temp - cache_file);
+       dir = g_path_get_dirname (cache_file);
 
        if (g_mkdir_with_parents (dir, 0700) == -1) {
                g_set_error (
diff --git a/src/camel/camel-ews-store.c b/src/camel/camel-ews-store.c
index 937fb2e..62d53c1 100644
--- a/src/camel/camel-ews-store.c
+++ b/src/camel/camel-ews-store.c
@@ -1975,7 +1975,7 @@ ews_rename_folder_sync (CamelStore *store,
                /* Folder basename changed (i.e. UpdateFolder needed).
                 * Therefore, we can only do it if the folder hasn't also
                 * been moved from one parent folder to another.
- *
+                *
                 * Strictly speaking, we could probably handle this, even
                 * if there are name collisions. We could UpdateFolder to
                 * a new temporary name that doesn't exist in either the
diff --git a/src/server/e-ews-connection.c b/src/server/e-ews-connection.c
index a484f84..8b37879 100644
--- a/src/server/e-ews-connection.c
+++ b/src/server/e-ews-connection.c
@@ -6085,13 +6085,9 @@ ews_handle_attachments_param (ESoapParameter *param,
                        info = e_ews_dump_file_attachment_from_soap_parameter (subparam, 
async_data->directory, async_data->sync_state, &attach_id);
                }
 
-               if (info && attach_id) {
+               if (info && attach_id)
                        async_data->items = g_slist_append (async_data->items, info);
-                       async_data->items_created = g_slist_append (async_data->items_created, attach_id);
-               } else {
-                       e_ews_attachment_info_free (info);
-                       g_free (attach_id);
-               }
+
                info = NULL;
                attach_id = NULL;
        }
diff --git a/src/server/e-ews-item.c b/src/server/e-ews-item.c
index 538b965..e5f5231 100644
--- a/src/server/e-ews-item.c
+++ b/src/server/e-ews-item.c
@@ -1499,26 +1499,33 @@ gchar *
 e_ews_embed_attachment_id_in_uri (const gchar *olduri,
                                   const gchar *attach_id)
 {
-       gchar *tmpdir, *tmpfilename, filename[350], dirname[350], *name;
+       gchar *tmpdir, *tmpfilename, *filename, *dirname, *name;
 
        tmpfilename = g_filename_from_uri (olduri, NULL, NULL);
+       g_return_val_if_fail (tmpfilename != NULL, NULL);
 
-       name = g_strrstr (tmpfilename, "/") + 1;
-       tmpdir = g_strndup (tmpfilename, g_strrstr (tmpfilename, "/") - tmpfilename);
+       name = g_path_get_basename (tmpfilename);
+       tmpdir = g_path_get_dirname (tmpfilename);
 
-       snprintf (dirname, 350, "%s/%s", tmpdir, attach_id);
+       dirname = g_build_filename (tmpdir, attach_id, NULL);
        if (g_mkdir (dirname, 0775) == -1) {
-               g_warning ("Failed create directory to place file in [%s]: %s\n", dirname, strerror (errno));
+               g_warning ("Failed create directory to place file in [%s]: %s\n", dirname, g_strerror 
(errno));
        }
 
-       snprintf (filename, 350, "%s/%s", dirname, name);
+       filename = g_build_filename (dirname, name, NULL);
        if (g_rename (tmpfilename, filename) != 0) {
-               g_warning ("Failed to move attachment cache file [%s -> %s]: %s\n", tmpfilename, filename, 
strerror (errno));
+               g_warning ("Failed to move attachment cache file [%s -> %s]: %s\n", tmpfilename, filename, 
g_strerror (errno));
        }
 
        g_free (tmpdir);
+       g_free (dirname);
+       g_free (name);
+
+       tmpfilename = g_filename_to_uri (filename, NULL, NULL);
 
-       return g_filename_to_uri (filename, NULL, NULL);
+       g_free (filename);
+
+       return tmpfilename;
 }
 
 EEwsAttachmentInfo *
@@ -1563,21 +1570,21 @@ e_ews_dump_file_attachment_from_soap_parameter (ESoapParameter *param,
                return NULL;
        }
 
-       if (cache) {
+       if (cache && content && g_file_test ((const gchar *) content, G_FILE_TEST_IS_REGULAR | 
G_FILE_TEST_EXISTS)) {
                info = e_ews_attachment_info_new (E_EWS_ATTACHMENT_INFO_TYPE_URI);
 
                tmpfilename = (gchar *) content;
-               tmpdir = g_strndup (tmpfilename, g_strrstr (tmpfilename, "/") - tmpfilename);
+               tmpdir = g_path_get_dirname (tmpfilename);
 
                dirname = g_build_filename (tmpdir, comp_uid, NULL);
                if (g_mkdir_with_parents (dirname, 0775) == -1) {
-                       g_warning ("Failed create directory to place file in [%s]: %s\n", dirname, strerror 
(errno));
+                       g_warning ("Failed create directory to place file in [%s]: %s\n", dirname, g_strerror 
(errno));
                }
 
                filename = g_build_filename (dirname, name, NULL);
                if (g_rename (tmpfilename, filename) != 0) {
                        g_warning ("Failed to move attachment cache file [%s -> %s]: %s\n",
-                                       tmpfilename, filename, strerror (errno));
+                                       tmpfilename, filename, g_strerror (errno));
                }
 
                g_free (dirname);
@@ -1599,28 +1606,44 @@ EEwsAttachmentInfo *
 e_ews_item_dump_mime_content (EEwsItem *item,
                               const gchar *cache)
 {
-       EEwsAttachmentInfo *info = e_ews_attachment_info_new (E_EWS_ATTACHMENT_INFO_TYPE_URI);
+       EEwsAttachmentInfo *info;
        gchar *filename, *surename, *dirname;
        gchar *tmpdir, *uri;
        const gchar *tmpfilename;
 
        g_return_val_if_fail (item->priv->mime_content != NULL, NULL);
+       g_return_val_if_fail (g_file_test ((const gchar *) item->priv->mime_content, G_FILE_TEST_IS_REGULAR | 
G_FILE_TEST_EXISTS), NULL);
 
        tmpfilename = (gchar *) item->priv->mime_content;
-       tmpdir = g_strndup (tmpfilename, g_strrstr (tmpfilename, "/") - tmpfilename);
+       tmpdir = g_path_get_dirname (tmpfilename);
 
        dirname = g_build_filename (tmpdir, "XXXXXX", NULL);
-       if (!mkdtemp (dirname))
-               g_warning ("Failed to create directory for attachment cache");
+       if (!mkdtemp (dirname)) {
+               g_warning ("Failed to create directory for attachment cache '%s': %s", dirname, g_strerror 
(errno));
+
+               g_free (tmpdir);
+               g_free (dirname);
+
+               return NULL;
+       }
 
        surename = g_uri_escape_string (item->priv->subject, "", TRUE);
        filename = g_build_filename (dirname, surename, NULL);
 
        if (g_rename ((const gchar *) item->priv->mime_content, filename) != 0) {
-               g_warning ("Failed to move attachment cache file");
+               g_warning ("Failed to move attachment cache file '%s': %s", filename, g_strerror (errno));
+
+               g_free (tmpdir);
+               g_free (dirname);
+               g_free (filename);
+               g_free (surename);
+
+               return NULL;
        }
 
        uri = g_filename_to_uri (filename, NULL, NULL);
+
+       info = e_ews_attachment_info_new (E_EWS_ATTACHMENT_INFO_TYPE_URI);
        e_ews_attachment_info_set_uri (info, uri);
 
        g_free (uri);
diff --git a/src/server/e-soap-message.c b/src/server/e-soap-message.c
index 5f17ce3..903b5f8 100644
--- a/src/server/e-soap-message.c
+++ b/src/server/e-soap-message.c
@@ -11,6 +11,7 @@
 
 #include <string.h>
 #include <stdio.h>
+#include <errno.h>
 #include <libsoup/soup.h>
 #ifdef G_OS_WIN32
 #include <io.h>
@@ -221,6 +222,10 @@ soap_sax_startElementNs (gpointer _ctxt,
                        g_free (enc);
                } else
                        xmlSAX2Characters (ctxt, (xmlChar *) fname, strlen (fname));
+       } else {
+               gint err = errno;
+
+               g_warning ("%s: Failed to create temp file '%s': %s\n", G_STRFUNC, fname, g_strerror (err));
        }
        g_free (fname);
 }


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