[evolution-data-server/gnome-3-16] Bug 705771 - Improve error handling in POP3 code



commit c7433db55a31b98daf5c645475b37f7a5f9b8568
Author: Milan Crha <mcrha redhat com>
Date:   Mon Apr 27 18:30:35 2015 +0200

    Bug 705771 - Improve error handling in POP3 code

 camel/providers/pop3/camel-pop3-engine.c |   26 ++++++++++++++++-------
 camel/providers/pop3/camel-pop3-folder.c |   33 +++++++++++++++++++++++++----
 camel/providers/pop3/camel-pop3-store.c  |   20 ++++++++++++-----
 camel/providers/pop3/camel-pop3-stream.c |    1 +
 4 files changed, 61 insertions(+), 19 deletions(-)
---
diff --git a/camel/providers/pop3/camel-pop3-engine.c b/camel/providers/pop3/camel-pop3-engine.c
index d541de7..dcbfc38 100644
--- a/camel/providers/pop3/camel-pop3-engine.c
+++ b/camel/providers/pop3/camel-pop3-engine.c
@@ -91,7 +91,8 @@ camel_pop3_engine_init (CamelPOP3Engine *engine)
 
 static gint
 read_greeting (CamelPOP3Engine *pe,
-               GCancellable *cancellable)
+               GCancellable *cancellable,
+              GError **error)
 {
        guchar *line, *apop, *apopend;
        guint len;
@@ -99,7 +100,7 @@ read_greeting (CamelPOP3Engine *pe,
        g_return_val_if_fail (pe != NULL, -1);
 
        /* first, read the greeting */
-       if (camel_pop3_stream_line (pe->stream, &line, &len, cancellable, NULL) == -1
+       if (camel_pop3_stream_line (pe->stream, &line, &len, cancellable, error) == -1
            || strncmp ((gchar *) line, "+OK", 3) != 0)
                return -1;
 
@@ -142,7 +143,7 @@ camel_pop3_engine_new (CamelStream *source,
        pe->state = CAMEL_POP3_ENGINE_AUTH;
        pe->flags = flags;
 
-       if (read_greeting (pe, cancellable) == -1 ||
+       if (read_greeting (pe, cancellable, error) == -1 ||
            !get_capabilities (pe, cancellable, error)) {
                g_object_unref (pe);
                return NULL;
@@ -239,12 +240,12 @@ get_capabilities (CamelPOP3Engine *pe,
        g_return_val_if_fail (pe != NULL, FALSE);
 
        if (!(pe->flags & CAMEL_POP3_ENGINE_DISABLE_EXTENSIONS)) {
-               pc = camel_pop3_engine_command_new (pe, CAMEL_POP3_COMMAND_MULTI, cmd_capa, NULL, 
cancellable, NULL, "CAPA\r\n");
-               while (camel_pop3_engine_iterate (pe, pc, cancellable, NULL) > 0)
+               pc = camel_pop3_engine_command_new (pe, CAMEL_POP3_COMMAND_MULTI, cmd_capa, NULL, 
cancellable, &local_error, "CAPA\r\n");
+               while (camel_pop3_engine_iterate (pe, pc, cancellable, &local_error) > 0)
                        ;
                camel_pop3_engine_command_free (pe, pc);
 
-               if (pe->state == CAMEL_POP3_ENGINE_TRANSACTION && !(pe->capa & CAMEL_POP3_CAP_UIDL)) {
+               if (!local_error && pe->state == CAMEL_POP3_ENGINE_TRANSACTION && !(pe->capa & 
CAMEL_POP3_CAP_UIDL)) {
                        /* check for UIDL support manually */
                        pc = camel_pop3_engine_command_new (pe, CAMEL_POP3_COMMAND_SIMPLE, NULL, NULL, 
cancellable, &local_error, "UIDL 1\r\n");
                        while (camel_pop3_engine_iterate (pe, pc, cancellable, &local_error) > 0)
@@ -333,8 +334,17 @@ camel_pop3_engine_iterate (CamelPOP3Engine *pe,
                        pc->state = CAMEL_POP3_COMMAND_DATA;
                        camel_pop3_stream_set_mode (pe->stream, CAMEL_POP3_STREAM_DATA);
 
-                       if (pc->func)
-                               pc->func (pe, pe->stream, cancellable, error, pc->func_data);
+                       if (pc->func) {
+                               GError *local_error = NULL;
+
+                               pc->func (pe, pe->stream, cancellable, &local_error, pc->func_data);
+                               if (local_error) {
+                                       pc->state = CAMEL_POP3_COMMAND_ERR;
+                                       pc->error_str = g_strdup (local_error->message);
+                                       g_propagate_error (error, local_error);
+                                       break;
+                               }
+                       }
 
                        /* Make sure we get all data before going back to command mode */
                        while (camel_pop3_stream_getd (pe->stream, &p, &len, cancellable, error) > 0)
diff --git a/camel/providers/pop3/camel-pop3-folder.c b/camel/providers/pop3/camel-pop3-folder.c
index 55753e4..9e1b465 100644
--- a/camel/providers/pop3/camel-pop3-folder.c
+++ b/camel/providers/pop3/camel-pop3-folder.c
@@ -478,6 +478,8 @@ pop3_folder_get_message_sync (CamelFolder *folder,
 
        /* check to see if we have safely written flag set */
        if (!camel_pop3_store_cache_has (pop3_store, fi->uid)) {
+               GError *local_error = NULL;
+
                /* Initiate retrieval, if disk backing fails, use a memory backing */
                stream = camel_pop3_store_cache_add (pop3_store, fi->uid, NULL);
                if (stream == NULL)
@@ -489,9 +491,19 @@ pop3_folder_get_message_sync (CamelFolder *folder,
                        pop3_engine,
                        CAMEL_POP3_COMMAND_MULTI,
                        cmd_tocache, fi,
-                       cancellable, error,
+                       cancellable, &local_error,
                        "RETR %u\r\n", fi->id);
 
+               if (local_error) {
+                       if (pcr)
+                               camel_pop3_engine_command_free (pop3_engine, pcr);
+
+                       g_propagate_error (error, local_error);
+                       g_prefix_error (
+                               error, _("Cannot get message %s: "), uid);
+                       goto done;
+               }
+
                /* Also initiate retrieval of some of the following
                 * messages, assume we'll be receiving them. */
                if (auto_fetch) {
@@ -511,15 +523,25 @@ pop3_folder_get_message_sync (CamelFolder *folder,
                                                        pop3_engine,
                                                        CAMEL_POP3_COMMAND_MULTI,
                                                        cmd_tocache, pfi,
-                                                       cancellable, error,
+                                                       cancellable, &local_error,
                                                        "RETR %u\r\n", pfi->id);
+
+                                                       if (local_error) {
+                                                               if (pcr)
+                                                                       camel_pop3_engine_command_free 
(pop3_engine, pcr);
+
+                                                               g_propagate_error (error, local_error);
+                                                               g_prefix_error (
+                                                                       error, _("Cannot get message %s: "), 
uid);
+                                                               goto done;
+                                                       }
                                        }
                                }
                        }
                }
 
                /* now wait for the first one to finish */
-               while ((i = camel_pop3_engine_iterate (pop3_engine, pcr, cancellable, error)) > 0)
+               while (!local_error && (i = camel_pop3_engine_iterate (pop3_engine, pcr, cancellable, 
&local_error)) > 0)
                        ;
 
                /* getting error code? */
@@ -529,7 +551,8 @@ pop3_folder_get_message_sync (CamelFolder *folder,
                        G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, NULL);
 
                /* Check to see we have safely written flag set */
-               if (i == -1) {
+               if (i == -1 || local_error) {
+                       g_propagate_error (error, local_error);
                        g_prefix_error (
                                error, _("Cannot get message %s: "), uid);
                        goto done;
@@ -649,7 +672,7 @@ pop3_folder_refresh_info_sync (CamelFolder *folder,
                        cmd_uidl, folder,
                        cancellable, &local_error,
                        "UIDL\r\n");
-       while ((i = camel_pop3_engine_iterate (pop3_engine, NULL, cancellable, &local_error)) > 0)
+       while (!local_error && (i = camel_pop3_engine_iterate (pop3_engine, NULL, cancellable, &local_error)) 
0)
                ;
 
        if (local_error) {
diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c
index 6ac3d49..9d83889 100644
--- a/camel/providers/pop3/camel-pop3-store.c
+++ b/camel/providers/pop3/camel-pop3-store.c
@@ -107,7 +107,7 @@ connect_to_server (CamelService *service,
        CamelNetworkSettings *network_settings;
        CamelNetworkSecurityMethod method;
        CamelSettings *settings;
-       CamelStream *stream;
+       CamelStream *stream = NULL;
        CamelPOP3Engine *pop3_engine = NULL;
        CamelPOP3Command *pc;
        GIOStream *base_stream;
@@ -219,7 +219,7 @@ connect_to_server (CamelService *service,
                goto stls_exception;
        }
 
-       g_object_unref (stream);
+       g_clear_object (&stream);
 
        /* rfc2595, section 4 states that after a successful STLS
         * command, the client MUST discard prior CAPA responses */
@@ -242,8 +242,7 @@ stls_exception:
        }*/
 
 exception:
-       g_object_unref (stream);
-
+       g_clear_object (&stream);
        g_clear_object (&pop3_engine);
 
        success = FALSE;
@@ -699,6 +698,14 @@ pop3_store_authenticate_sync (CamelService *service,
                        pop3_engine, 0, NULL, NULL, cancellable, error,
                        "PASS %s\r\n", password);
 
+               if (error && *error) {
+                       g_prefix_error (
+                               error,
+                               _("Unable to connect to POP server %s.\n"
+                               "Error sending password: "), host);
+                       result = CAMEL_AUTHENTICATION_ERROR;
+                       goto exit;
+               }
        } else if (strcmp (mechanism, "+APOP") == 0 && pop3_engine->apop) {
                gchar *secret, *md5asc, *d;
                gsize secret_len;
@@ -803,12 +810,13 @@ pop3_store_authenticate_sync (CamelService *service,
                result = CAMEL_AUTHENTICATION_ACCEPTED;
        }
 
-       camel_pop3_engine_command_free (pop3_engine, pcp);
+exit:
+       if (pcp != NULL)
+               camel_pop3_engine_command_free (pop3_engine, pcp);
 
        if (pcu != NULL)
                camel_pop3_engine_command_free (pop3_engine, pcu);
 
-exit:
        g_free (host);
        g_free (user);
 
diff --git a/camel/providers/pop3/camel-pop3-stream.c b/camel/providers/pop3/camel-pop3-stream.c
index 6d921f7..dba6feb 100644
--- a/camel/providers/pop3/camel-pop3-stream.c
+++ b/camel/providers/pop3/camel-pop3-stream.c
@@ -80,6 +80,7 @@ stream_fill (CamelPOP3Stream *is,
                        cancellable, &local_error);
                if (local_error) {
                        g_propagate_error (error, local_error);
+                       left = 0;
                }
 
                if (left > 0) {


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