@@ -776,9 +776,12 @@ static int process_fetch_finalize(struct imap_session *imap, struct fetch_reques
776776 }
777777 }
778778
779- imap_send_nocrlf (imap , /* Start the IMAP response, and ensure no CR LF is automatically added. */
779+ if ( imap_send_nocrlf (imap , /* Start the IMAP response, and ensure no CR LF is automatically added. */
780780 "* %d " /* Number after FETCH is always a message sequence number, not UID, even if usinguid */
781- "FETCH (%s" , seqno , response ); /* No closing paren, we do that at the very end */
781+ "FETCH (%s" , seqno , response ) < 0 ) { /* No closing paren, we do that at the very end */
782+ res = -1 ;
783+ goto cleanup ;
784+ }
782785
783786 /* Now, send anything that could be a large, variable amount of data.
784787 * All of these will use a format literal / multiline response */
@@ -950,21 +953,21 @@ static int process_fetch(struct imap_session *imap, int usinguid, struct fetch_r
950953 int markseen , recent ;
951954
952955 if (entry -> d_type != DT_REG || !strcmp (entry -> d_name , "." ) || !strcmp (entry -> d_name , ".." )) {
953- goto cleanup ;
956+ goto next ;
954957 }
955958 msguid = imap_msg_in_range (imap , ++ seqno , entry -> d_name , sequences , usinguid , & error );
956959 if (!msguid ) {
957- goto cleanup ;
960+ goto next ;
958961 }
959962 if (fetchreq -> changedsince ) {
960963 if (parse_modseq_from_filename (entry -> d_name , & modseq )) {
961- goto cleanup ;
964+ goto next ;
962965 }
963966 if (modseq <= fetchreq -> changedsince ) {
964967#ifdef EXTRA_DEBUG
965968 bbs_debug (5 , "modseq %lu older than CHANGEDSINCE %lu\n" , modseq , fetchreq -> changedsince );
966969#endif
967- goto cleanup ; /* Older than specified CHANGEDSINCE */
970+ goto next ; /* Older than specified CHANGEDSINCE */
968971 }
969972 }
970973 /* At this point, the message is a match. Fetch everything we're supposed to for it. */
@@ -997,19 +1000,19 @@ static int process_fetch(struct imap_session *imap, int usinguid, struct fetch_r
9971000 */
9981001 recent = (unsigned int ) seqno >= imap -> minrecent && (unsigned int ) seqno <= imap -> maxrecent ;
9991002 if (fetchreq -> flags && process_fetch_flags (imap , entry -> d_name , markseen , recent , response , sizeof (response ), & buf , & len )) {
1000- goto cleanup ;
1003+ goto next ;
10011004 }
10021005 if (fetchreq -> rfc822size && process_fetch_size (entry -> d_name , response , sizeof (response ), & buf , & len )) {
1003- goto cleanup ;
1006+ goto next ;
10041007 }
10051008 if (fetchreq -> modseq && process_fetch_modseq (entry -> d_name , response , sizeof (response ), & buf , & len , & modseq )) {
1006- goto cleanup ;
1009+ goto next ;
10071010 }
10081011 if (fetchreq -> internaldate && process_fetch_internaldate (fullname , response , sizeof (response ), & buf , & len )) {
1009- goto cleanup ;
1012+ goto next ;
10101013 }
10111014 if (fetchreq -> envelope && process_fetch_envelope (fullname , response , sizeof (response ), & buf , & len )) {
1012- goto cleanup ;
1015+ goto next ;
10131016 }
10141017
10151018 /* Handle the header/body stuff and actually send the response. */
@@ -1020,10 +1023,16 @@ static int process_fetch(struct imap_session *imap, int usinguid, struct fetch_r
10201023 mark_seen (imap , seqno , fullname , entry -> d_name ); /* No need to goto cleanup if we fail, we do anyways */
10211024 }
10221025
1026+ next :
10231027 fetched ++ ;
1028+ free (entry );
1029+ continue ;
10241030
10251031cleanup :
1032+ /* For example, if there was an I/O error during the FETCH response, abort immediately.
1033+ * This is not uncommon - a client could exit in the middle of a FETCH 1:* */
10261034 free (entry );
1035+ break ;
10271036 }
10281037 free (entries );
10291038 if (!fetched ) {
0 commit comments