commit 45b11c63a503dd53674ead6f8617af61e7563b78 Author: Oswald Buddenhagen <o...@kde.org> Date: Tue Oct 16 09:27:58 2012 +0200
more error checking of IMAP responses REFMAIL: CA+Tk8fyu-6bwXq=ee2BgcKK_13m9S0RS+-0DhM=_jfqskch...@mail.gmail.com src/drv_imap.c | 48 +++++++++++++++++++++++++++++++++--------------- 1 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/drv_imap.c b/src/drv_imap.c index 50a3eb2..3e10897 100644 --- a/src/drv_imap.c +++ b/src/drv_imap.c @@ -535,6 +535,8 @@ parse_imap_list( imap_store_t *ctx, char **sp, parse_list_state_t *sts ) goto getbytes; } + if (!s) + return LIST_BAD; for (;;) { while (isspace( (unsigned char)*s )) s++; @@ -785,7 +787,7 @@ parse_response_code( imap_store_t *ctx, struct imap_cmd *cmd, char *s ) { char *arg, *earg, *p; - if (*s != '[') + if (!s || *s != '[') return RESP_OK; /* no response code */ s++; if (!(p = strchr( s, ']' ))) { @@ -827,19 +829,20 @@ parse_response_code( imap_store_t *ctx, struct imap_cmd *cmd, char *s ) return RESP_OK; } -static void +static int parse_list_rsp( imap_store_t *ctx, char *cmd ) { char *arg; list_t *list, *lp; int l; - list = parse_list( &cmd ); + if (!(list = parse_list( &cmd ))) + return -1; if (list->val == LIST) for (lp = list->child; lp; lp = lp->next) if (is_atom( lp ) && !strcasecmp( lp->val, "\\NoSelect" )) { free_list( list ); - return; + return 0; } free_list( list ); arg = next_arg( &cmd ); @@ -849,21 +852,22 @@ parse_list_rsp( imap_store_t *ctx, char *cmd ) if (memcmp( arg, "INBOX", 5 ) || (arg[5] && arg[5] != ctx->delimiter)) { l = strlen( ctx->gen.conf->path ); if (memcmp( arg, ctx->gen.conf->path, l )) - return; + return 0; arg += l; if (!memcmp( arg, "INBOX", 5 ) && (!arg[5] || arg[5] == ctx->delimiter)) { if (!arg[5]) warn( "IMAP warning: ignoring INBOX in %s\n", ctx->gen.conf->path ); - return; + return 0; } } if (!memcmp( arg + strlen( arg ) - 5, ".lock", 5 )) /* workaround broken servers */ - return; + return 0; if (map_name( arg, ctx->delimiter, '/') < 0) { warn( "IMAP warning: ignoring mailbox %s (reserved character '/' in name)\n", arg ); - return; + return 0; } add_string_list( &ctx->gen.boxes, arg ); + return 0; } static int @@ -925,6 +929,10 @@ imap_socket_read( void *aux ) return; arg = next_arg( &cmd ); + if (!arg) { + error( "IMAP error: empty response\n" ); + break; + } if (*arg == '*') { arg = next_arg( &cmd ); if (!arg) { @@ -933,9 +941,12 @@ imap_socket_read( void *aux ) } if (!strcmp( "NAMESPACE", arg )) { - ctx->ns_personal = parse_list( &cmd ); - ctx->ns_other = parse_list( &cmd ); - ctx->ns_shared = parse_list( &cmd ); + if (!(ctx->ns_personal = parse_list( &cmd )) || + !(ctx->ns_other = parse_list( &cmd )) || + !(ctx->ns_shared = parse_list( &cmd ))) { + error( "IMAP error: malformed NAMESPACE response\n" ); + break; + } } else if (ctx->greeting == GreetingPending && !strcmp( "PREAUTH", arg )) { ctx->greeting = GreetingPreauth; parse_response_code( ctx, 0, cmd ); @@ -945,11 +956,14 @@ imap_socket_read( void *aux ) } else if (!strcmp( "BAD", arg ) || !strcmp( "NO", arg ) || !strcmp( "BYE", arg )) { ctx->greeting = GreetingBad; parse_response_code( ctx, 0, cmd ); - } else if (!strcmp( "CAPABILITY", arg )) + } else if (!strcmp( "CAPABILITY", arg )) { parse_capability( ctx, cmd ); - else if (!strcmp( "LIST", arg )) - parse_list_rsp( ctx, cmd ); - else if ((arg1 = next_arg( &cmd ))) { + } else if (!strcmp( "LIST", arg )) { + if (parse_list_rsp( ctx, cmd ) < 0) { + error( "IMAP error: malformed LIST response\n" ); + break; + } + } else if ((arg1 = next_arg( &cmd ))) { if (!strcmp( "EXISTS", arg1 )) ctx->gen.count = atoi( arg ); else if (!strcmp( "RECENT", arg1 )) @@ -1010,6 +1024,10 @@ imap_socket_read( void *aux ) ctx->in_progress_append = pcmdp; ctx->num_in_progress--; arg = next_arg( &cmd ); + if (!arg) { + error( "IMAP error: malformed tagged response\n" ); + break; + } if (!strcmp( "OK", arg )) { if (cmdp->param.to_trash) ctx->trashnc = TrashKnown; /* Can't get NO [TRYCREATE] any more. */ ------------------------------------------------------------------------------ Don't let slow site performance ruin your business. Deploy New Relic APM Deploy New Relic app performance management and know exactly what is happening inside your Ruby, Python, PHP, Java, and .NET app Try New Relic at no cost today and get our sweet Data Nerd shirt too! http://p.sf.net/sfu/newrelic-dev2dev _______________________________________________ isync-devel mailing list isync-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/isync-devel