commit a5a8783ea3de982dfd7c3926646033919bbf6af3
Author: Oswald Buddenhagen <o...@users.sf.net>
Date:   Mon Nov 11 14:29:42 2019 +0100

    sanitize error handling in IMAP FETCH response processing
    
    abort on actual error conditions (protocol errors) and downgrade the
    rest to warnings.
    
    REFMAIL: 20191102164509.dxayakg3hrmozjnm@carbon

 src/drv_imap.c | 51 ++++++++++++++++++++++++++++++++++----------------
 1 file changed, 35 insertions(+), 16 deletions(-)

diff --git a/src/drv_imap.c b/src/drv_imap.c
index dbc9c5f..4d3a038 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -968,8 +968,8 @@ parse_date( const char *str )
 static int
 parse_fetch_rsp( imap_store_t *ctx, list_t *list, char *s ATTR_UNUSED )
 {
-       list_t *tmp, *flags;
-       char *body = NULL, *tuid = NULL, *msgid = NULL, *ep;
+       list_t *body = NULL, *tmp, *flags;
+       char *tuid = NULL, *msgid = NULL, *ep;
        imap_message_t *cur;
        msg_data_t *msgdata;
        imap_cmd_t *cmdp;
@@ -986,8 +986,10 @@ parse_fetch_rsp( imap_store_t *ctx, list_t *list, char *s 
ATTR_UNUSED )
                if (is_atom( tmp )) {
                        if (!strcmp( "UID", tmp->val )) {
                                tmp = tmp->next;
-                               if (!is_atom( tmp ) || (uid = strtoul( 
tmp->val, &ep, 10 ), *ep))
+                               if (!is_atom( tmp ) || (uid = strtoul( 
tmp->val, &ep, 10 ), *ep)) {
                                        error( "IMAP error: unable to parse 
UID\n" );
+                                       goto ffail;
+                               }
                        } else if (!strcmp( "FLAGS", tmp->val )) {
                                tmp = tmp->next;
                                if (is_list( tmp )) {
@@ -1007,34 +1009,44 @@ parse_fetch_rsp( imap_store_t *ctx, list_t *list, char 
*s ATTR_UNUSED )
                                                                        goto 
flagok; /* ignore unknown user-defined flags (keywords) */
                                                                if 
(flags->val[0] == '\\' && flags->val[1] == 'X' && flags->val[2] == '-')
                                                                        goto 
flagok; /* ignore system flag extensions */
-                                                               error( "IMAP 
warning: unknown system flag %s\n", flags->val );
+                                                               warn( "IMAP 
warning: unknown system flag %s\n", flags->val );
                                                        }
                                                  flagok: ;
-                                               } else
+                                               } else {
                                                        error( "IMAP error: 
unable to parse FLAGS list\n" );
+                                                       goto ffail;
+                                               }
                                        }
                                        status |= M_FLAGS;
-                               } else
+                               } else {
                                        error( "IMAP error: unable to parse 
FLAGS\n" );
+                                       goto ffail;
+                               }
                        } else if (!strcmp( "INTERNALDATE", tmp->val )) {
                                tmp = tmp->next;
                                if (is_atom( tmp )) {
-                                       if ((date = parse_date( tmp->val )) == 
-1)
+                                       if ((date = parse_date( tmp->val )) == 
-1) {
                                                error( "IMAP error: unable to 
parse INTERNALDATE format\n" );
-                               } else
+                                               goto ffail;
+                                       }
+                               } else {
                                        error( "IMAP error: unable to parse 
INTERNALDATE\n" );
+                                       goto ffail;
+                               }
                        } else if (!strcmp( "RFC822.SIZE", tmp->val )) {
                                tmp = tmp->next;
-                               if (!is_atom( tmp ) || (size = strtoul( 
tmp->val, &ep, 10 ), *ep))
+                               if (!is_atom( tmp ) || (size = strtoul( 
tmp->val, &ep, 10 ), *ep)) {
                                        error( "IMAP error: unable to parse 
RFC822.SIZE\n" );
+                                       goto ffail;
+                               }
                        } else if (!strcmp( "BODY[]", tmp->val )) {
                                tmp = tmp->next;
                                if (is_atom( tmp )) {
-                                       body = tmp->val;
-                                       tmp->val = NULL;       /* don't free 
together with list */
-                                       size = tmp->len;
-                               } else
+                                       body = tmp;
+                               } else {
                                        error( "IMAP error: unable to parse 
BODY[]\n" );
+                                       goto ffail;
+                               }
                        } else if (!strcmp( "BODY[HEADER.FIELDS", tmp->val )) {
                                tmp = tmp->next;
                                if (is_list( tmp )) {
@@ -1053,7 +1065,7 @@ parse_fetch_rsp( imap_store_t *ctx, list_t *list, char *s 
ATTR_UNUSED )
                                                        break;
                                                if (starts_with_upper( val, 
len, "X-TUID: ", 8 )) {
                                                        if (len < 8 + TUIDL) {
-                                                               error( "IMAP 
error: malformed X-TUID header (UID %u)\n", uid );
+                                                               warn( "IMAP 
warning: malformed X-TUID header (UID %u)\n", uid );
                                                                continue;
                                                        }
                                                        tuid = val + 8;
@@ -1083,6 +1095,7 @@ parse_fetch_rsp( imap_store_t *ctx, list_t *list, char *s 
ATTR_UNUSED )
                                } else {
                                  bfail:
                                        error( "IMAP error: unable to parse 
BODY[HEADER.FIELDS ...]\n" );
+                                       goto ffail;
                                }
                        }
                }
@@ -1104,8 +1117,9 @@ parse_fetch_rsp( imap_store_t *ctx, list_t *list, char *s 
ATTR_UNUSED )
                return LIST_BAD;
          gotuid:
                msgdata = ((imap_cmd_fetch_msg_t *)cmdp)->msg_data;
-               msgdata->data = body;
-               msgdata->len = size;
+               msgdata->data = body->val;
+               body->val = NULL;       // Don't free together with list.
+               msgdata->len = body->len;
                msgdata->date = date;
                if (status & M_FLAGS)
                        msgdata->flags = mask;
@@ -1127,6 +1141,11 @@ parse_fetch_rsp( imap_store_t *ctx, list_t *list, char 
*s ATTR_UNUSED )
        }
 
        return LIST_OK;
+
+  ffail:
+       free( tuid );
+       free( msgid );
+       return LIST_BAD;
 }
 
 static void


_______________________________________________
isync-devel mailing list
isync-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to