Browse code

Handle more formats for end of line

git-svn: trunk@1483

Nigel Horne authored on 2005/04/19 18:23:12
Showing 2 changed files
... ...
@@ -1,3 +1,8 @@
1
+Tue Apr 19 10:22:26 BST 2005 (njh)
2
+----------------------------------
3
+  * libclamav/mbox.c:	Some Sober.N were getting through, thanks to Christoph
4
+				for pointing this out
5
+
1 6
 Tue Apr 19 01:26:56 CEST 2005 (tk)
2 7
 ----------------------------------
3 8
   * libclamav/unrarlib.[ch]: removed
... ...
@@ -15,7 +15,7 @@
15 15
  *  along with this program; if not, write to the Free Software
16 16
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 17
  */
18
-static	char	const	rcsid[] = "$Id: mbox.c,v 1.237 2005/04/13 09:10:29 nigelhorne Exp $";
18
+static	char	const	rcsid[] = "$Id: mbox.c,v 1.238 2005/04/19 09:20:55 nigelhorne Exp $";
19 19
 
20 20
 #if HAVE_CONFIG_H
21 21
 #include "clamav-config.h"
... ...
@@ -188,6 +188,7 @@ static	int	rfc1341(message *m, const char *dir);
188 188
 #endif
189 189
 static	bool	usefulHeader(int commandNumber, const char *cmd);
190 190
 static	void	uufasttrack(message *m, const char *firstline, const char *dir, FILE *fin);
191
+static	char	*getline(char *buffer, size_t len, FILE *fin);
191 192
 #ifdef	NEW_WORLD
192 193
 static	const	char	*cli_pmemstr(const char *haystack, size_t hs, const char *needle, size_t ns);
193 194
 #endif
... ...
@@ -430,7 +431,7 @@ cli_mbox(const char *dir, int desc, unsigned int options)
430 430
 					cli_dbgmsg("s = %u\n", s);
431 431
 					continue;	/* false positive */
432 432
 			}
433
-			
433
+
434 434
 		cli_dbgmsg("Found quoted-printable\n");
435 435
 		if(scanelem) {
436 436
 			scanelem->next = cli_malloc(sizeof(struct scanlist));
... ...
@@ -908,7 +909,7 @@ cli_parse_mbox(const char *dir, int desc, unsigned int options)
908 908
 		 * Ignore any blank lines at the top of the message
909 909
 		 */
910 910
 		while(strchr("\r\n", buffer[0]) &&
911
-		     (fgets(buffer, sizeof(buffer) - 1, fd) != NULL))
911
+		     (getline(buffer, sizeof(buffer) - 1, fd) != NULL))
912 912
 			;
913 913
 
914 914
 		buffer[sizeof(buffer) - 1] = '\0';
... ...
@@ -977,18 +978,14 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch
977 977
 
978 978
 	strcpy(buffer, firstLine);
979 979
 	do {
980
-		const char *start;
980
+		char *line;
981 981
 
982 982
 		(void)cli_chomp(buffer);
983
-		/*
984
-		 * Ignore leading CR, e.g. if newlines are LFCR instead
985
-		 * or CRLF
986
-		 */
987
-		for(start = buffer; *start == '\r'; start++)
988
-			;
989 983
 
990
-		if(start[0] == '\0')
991
-			start = NULL;
984
+		line = buffer;
985
+
986
+		if(line[0] == '\0')
987
+			line = NULL;
992 988
 
993 989
 		/*
994 990
 		 * Don't blank lines which are only spaces from headers,
... ...
@@ -1008,7 +1005,7 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch
1008 1008
 		if(inHeader) {
1009 1009
 			cli_dbgmsg("parseEmailFile: check '%s' contMarker %d fullline 0x%p\n",
1010 1010
 				buffer ? buffer : "", (int)contMarker, fullline);
1011
-			if(start && isspace(start[0])) {
1011
+			if(line && isspace(line[0])) {
1012 1012
 				char copy[sizeof(buffer)];
1013 1013
 
1014 1014
 				strcpy(copy, buffer);
... ...
@@ -1041,7 +1038,7 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch
1041 1041
 				}
1042 1042
 			}
1043 1043
 			lastWasBlank = FALSE;
1044
-			if((start == NULL) && (fullline == NULL)) {	/* empty line */
1044
+			if((line == NULL) && (fullline == NULL)) {	/* empty line */
1045 1045
 				if(!contMarker) {
1046 1046
 					/*
1047 1047
 					 * A blank line signifies the end of
... ...
@@ -1066,17 +1063,17 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch
1066 1066
 					/*
1067 1067
 					 * Continuation of line we're ignoring?
1068 1068
 					 */
1069
-					if((start[0] == '\t') || (start[0] == ' ') || contMarker) {
1070
-						contMarker = continuationMarker(start);
1069
+					if((line[0] == '\t') || (line[0] == ' ') || contMarker) {
1070
+						contMarker = continuationMarker(line);
1071 1071
 						continue;
1072 1072
 					}
1073 1073
 
1074 1074
 					/*
1075 1075
 					 * Is this a header we're interested in?
1076 1076
 					 */
1077
-					if((strchr(start, ':') == NULL) ||
1078
-					   (cli_strtokbuf(start, 0, ":", cmd) == NULL)) {
1079
-						if(strncmp(start, "From ", 5) == 0)
1077
+					if((strchr(line, ':') == NULL) ||
1078
+					   (cli_strtokbuf(line, 0, ":", cmd) == NULL)) {
1079
+						if(strncmp(line, "From ", 5) == 0)
1080 1080
 							anyHeadersFound = TRUE;
1081 1081
 						continue;
1082 1082
 					}
... ...
@@ -1095,16 +1092,16 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch
1095 1095
 								anyHeadersFound = usefulHeader(commandNumber, cmd);
1096 1096
 							continue;
1097 1097
 					}
1098
-					fullline = strdup(start);
1099
-					fulllinelength = strlen(start) + 1;
1100
-				} else if(start != NULL) {
1101
-					fulllinelength += strlen(start);
1098
+					fullline = strdup(line);
1099
+					fulllinelength = strlen(line) + 1;
1100
+				} else if(line != NULL) {
1101
+					fulllinelength += strlen(line);
1102 1102
 					fullline = cli_realloc(fullline, fulllinelength);
1103
-					strcat(fullline, start);
1103
+					strcat(fullline, line);
1104 1104
 				}
1105 1105
 
1106
-				if(start) {
1107
-					contMarker = continuationMarker(start);
1106
+				if(line) {
1107
+					contMarker = continuationMarker(line);
1108 1108
 
1109 1109
 					if(contMarker)
1110 1110
 						continue;
... ...
@@ -1128,7 +1125,7 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch
1128 1128
 						continue;
1129 1129
 				}
1130 1130
 
1131
-				if(start) {
1131
+				if(line) {
1132 1132
 					int quotes = 0;
1133 1133
 					for(qptr = fullline; *qptr; qptr++)
1134 1134
 						if(*qptr == '\"')
... ...
@@ -1150,16 +1147,16 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch
1150 1150
 				free(fullline);
1151 1151
 				fullline = NULL;
1152 1152
 			}
1153
-		} else if(start && isuuencodebegin(start))
1153
+		} else if(line && isuuencodebegin(line))
1154 1154
 			/*
1155 1155
 			 * Fast track visa to uudecode.
1156 1156
 			 * TODO: binhex, yenc
1157 1157
 			 */
1158
-			uufasttrack(ret, start, dir, fin);
1158
+			uufasttrack(ret, line, dir, fin);
1159 1159
 		else
1160
-			if(messageAddStr(ret, start) < 0)
1160
+			if(messageAddStr(ret, line) < 0)
1161 1161
 				break;
1162
-	} while(fgets(buffer, sizeof(buffer) - 1, fin) != NULL);
1162
+	} while(getline(buffer, sizeof(buffer) - 1, fin) != NULL);
1163 1163
 
1164 1164
 	if(fullline) {
1165 1165
 		if(*fullline) switch(commandNumber) {
... ...
@@ -2024,6 +2021,9 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
2024 2024
 
2025 2025
 					switch(messageGetMimeType(aMessage)) {
2026 2026
 					case APPLICATION:
2027
+					case AUDIO:
2028
+					case IMAGE:
2029
+					case VIDEO:
2027 2030
 						break;
2028 2031
 					case NOMIME:
2029 2032
 						cli_dbgmsg("No mime headers found in multipart part %d\n", i);
... ...
@@ -2201,10 +2201,6 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
2201 2201
 							mainMessage = NULL;
2202 2202
 						}
2203 2203
 						continue;
2204
-					case AUDIO:
2205
-					case IMAGE:
2206
-					case VIDEO:
2207
-						break;
2208 2204
 					default:
2209 2205
 						cli_warnmsg("Only text and application attachments are supported, type = %d\n",
2210 2206
 							messageGetMimeType(aMessage));
... ...
@@ -3882,6 +3878,62 @@ uufasttrack(message *m, const char *firstline, const char *dir, FILE *fin)
3882 3882
 	fileblobDestroy(fb);
3883 3883
 }
3884 3884
 
3885
+/*
3886
+ * Like fgets but cope with end of line by "\n", "\r\n", "\n\r", "\r"
3887
+ */
3888
+static char *
3889
+getline(char *buffer, size_t len, FILE *fin)
3890
+{
3891
+	char *ret;
3892
+
3893
+	if(feof(fin))
3894
+		return NULL;
3895
+
3896
+	if((len == 0) || (buffer == NULL)) {
3897
+		cli_errmsg("Invalid call to getline(). Report to bugs@clamav.net\n");
3898
+		return NULL;
3899
+	}
3900
+
3901
+	ret = buffer;
3902
+
3903
+	do {
3904
+		int c = getc(fin);
3905
+
3906
+		if(ferror(fin))
3907
+			return NULL;
3908
+
3909
+		switch(c) {
3910
+			case '\n':
3911
+				*buffer++ = '\n';
3912
+				c = getc(fin);
3913
+				if((c != '\r') && !feof(fin))
3914
+					ungetc(c, fin);
3915
+				break;
3916
+			default:
3917
+				*buffer++ = c;
3918
+				continue;
3919
+			case EOF:
3920
+				break;
3921
+			case '\r':
3922
+				*buffer++ = '\n';
3923
+				c = getc(fin);
3924
+				if((c != '\n') && !feof(fin))
3925
+					ungetc(c, fin);
3926
+				break;
3927
+		}
3928
+		break;
3929
+	} while(--len > 0);
3930
+
3931
+	if(len == 0) {
3932
+		/* probably, the email breaks RFC821 */
3933
+		cli_dbgmsg("getline: buffer overflow stopped\n");
3934
+		return NULL;
3935
+	}
3936
+	*buffer = '\0';
3937
+
3938
+	return ret;
3939
+}
3940
+
3885 3941
 #ifdef	NEW_WORLD
3886 3942
 /*
3887 3943
  * like cli_memstr - but returns the location of the match