[dovecot-cvs] dovecot/src/lib-index/mbox mbox-index.c,1.43,1.44

cras at procontrol.fi cras at procontrol.fi
Tue Nov 5 09:58:59 EET 2002


Update of /home/cvs/dovecot/src/lib-index/mbox
In directory danu:/tmp/cvs-serv22424

Modified Files:
	mbox-index.c 
Log Message:
Fixes for parsing mbox messages when ending \n in header actually belongs to
next From-line (eg. "\n\nFrom").



Index: mbox-index.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mbox/mbox-index.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
--- mbox-index.c	2 Nov 2002 20:10:20 -0000	1.43
+++ mbox-index.c	5 Nov 2002 07:58:57 -0000	1.44
@@ -477,12 +477,12 @@
 static void mbox_skip_forward(IBuffer *inbuf, int header)
 {
 	const unsigned char *msg;
-	size_t i, size, startpos;
+	size_t i, size, startpos, eoh;
 	int lastmsg, state, new_state;
 
 	/* read until "[\r]\nFrom " is found. assume '\n' at beginning of
 	   buffer */
-	startpos = i = 0; lastmsg = TRUE;
+	startpos = i = 0; eoh = 0; lastmsg = TRUE;
 	state = '\n';
 	while (i_buffer_read_data(inbuf, &msg, &size, startpos) > 0) {
 		for (i = startpos; i < size; i++) {
@@ -493,20 +493,25 @@
 					new_state = 'F';
 				else if (header) {
 					if (msg[i] == '\n') {
-						/* \n\n */
-						i_buffer_skip(inbuf, i+1);
-						return;
-					}
-
-					if (msg[i] == '\r')
+						/* \n\n, but if we have
+						   0-byte message body the
+						   following \n may belong
+						   to "From "-line */
+						eoh = i+1;
+						header = FALSE;
+						new_state = '\n';
+					} else if (msg[i] == '\r') {
+						/* possibly \n\r\n */
 						new_state = '\r';
+					}
 				}
 				break;
 			case '\r':
 				if (msg[i] == '\n') {
 					/* \n\r\n */
-					i_buffer_skip(inbuf, i+1);
-					return;
+					eoh = i+1;
+					header = FALSE;
+					new_state = '\n';
 				}
 				break;
 			case 'F':
@@ -543,17 +548,37 @@
 				break;
 			}
 
-			if (new_state == 0 && msg[i] == '\n')
-				state = '\n';
-			else
+			if (new_state != 0)
 				state = new_state;
+			else if (eoh == 0)
+				state = msg[i] == '\n' ? '\n' : 0;
+			else {
+				/* end of header position confirmed */
+				i_buffer_skip(inbuf, eoh);
+				return;
+			}
 		}
 
-		/* Leave enough space to go back "\r\nFrom" */
-		startpos = i < 6 ? i : 6;
+		/* Leave enough space to go back "\r\nFrom" plus one for the
+		   end-of-headers check */
+		startpos = i < 7 ? i : 7;
 		i -= startpos;
 
+		if (eoh != 0) {
+			i_assert(i < eoh);
+			eoh -= i;
+		}
+
 		i_buffer_skip(inbuf, i);
+	}
+
+	if (eoh != 0) {
+		/* make sure we didn't end with \n\n or \n\r\n. In these
+		   cases the last [\r]\n doesn't belong to our message. */
+		if (eoh < size && (msg[eoh] != '\r' || eoh < size-1)) {
+			i_buffer_skip(inbuf, eoh);
+			return;
+		}
 	}
 
 	/* end of file, leave the last [\r]\n */




More information about the dovecot-cvs mailing list