Browse code

Multiparts now only create an array when needed

git-svn: trunk@2061

Nigel Horne authored on 2006/07/03 21:09:58
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+Mon Jul  3 13:09:27 BST 2006 (njh)
2
+----------------------------------
3
+  * libclamav/mbox.c:	Multiparts now only create an array when needed
4
+
1 5
 Sat Jul  1 22:04:04 BST 2006 (njh)
2 6
 ----------------------------------
3 7
   * libclamav:	More freeing memory earlier
... ...
@@ -16,7 +16,7 @@
16 16
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 17
  *  MA 02110-1301, USA.
18 18
  */
19
-static	char	const	rcsid[] = "$Id: mbox.c,v 1.316 2006/07/03 09:19:15 njh Exp $";
19
+static	char	const	rcsid[] = "$Id: mbox.c,v 1.317 2006/07/03 12:08:55 njh Exp $";
20 20
 
21 21
 #if HAVE_CONFIG_H
22 22
 #include "clamav-config.h"
... ...
@@ -2085,18 +2085,25 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
2085 2085
 			inMimeHead = 0;
2086 2086
 
2087 2087
 			/*
2088
+			 * Re-read this variable in case mimeSubtype has changed
2089
+			 */
2090
+			subtype = tableFind(mctx->subtypeTable, mimeSubtype);
2091
+
2092
+			/*
2088 2093
 			 * Parse the mainMessage object and create an array
2089 2094
 			 * of objects called messages, one for each of the
2090
-			 * multiparts that mainMessage contains
2091
-			 *
2092
-			 * TODO: The array is probably no longer needed, we can
2093
-			 * export to file each time around the loop rather than
2094
-			 * add to the array
2095
+			 * multiparts that mainMessage contains.
2095 2096
 			 *
2096 2097
 			 * This looks like parseEmailHeaders() - maybe there's
2097 2098
 			 * some duplication of code to be cleaned up
2099
+			 *
2100
+			 * We need to create an array rather than just
2101
+			 * save each part as it is found because not all
2102
+			 * elements will need scanning, and we don't yet know
2103
+			 * which of those elements it will be, except in
2104
+			 * the case of mixed, when all parts need to be scanned.
2098 2105
 			 */
2099
-			for(multiparts = 0; t_line; multiparts++) {
2106
+			for(multiparts = 0; t_line && !infected; multiparts++) {
2100 2107
 				int lines = 0;
2101 2108
 				message **m;
2102 2109
 
... ...
@@ -2133,7 +2140,8 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
2133 2133
 					 * throw away by mistake if the MIME
2134 2134
 					 * encoding information is incorrect
2135 2135
 					 */
2136
-					if(binhexBegin(mainMessage) == NULL) {
2136
+					if(mainMessage &&
2137
+					   (binhexBegin(mainMessage) == NULL)) {
2137 2138
 						messageDestroy(aMessage);
2138 2139
 						--multiparts;
2139 2140
 					}
... ...
@@ -2350,10 +2358,34 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
2350 2350
 					}
2351 2351
 				} while((t_line = t_line->t_next) != NULL);
2352 2352
 
2353
-				messageClean(aMessage);
2354
-
2355 2353
 				cli_dbgmsg("Part %d has %d lines\n",
2356 2354
 					multiparts, lines);
2355
+
2356
+				/*
2357
+				 * Only save in the array of messages if some
2358
+				 * decision will be taken on whether to scan.
2359
+				 * If all parts will be scanned then save to
2360
+				 * file straight away
2361
+				 */
2362
+				switch(subtype) {
2363
+					case MIXED:
2364
+					case ALTERNATIVE:
2365
+					case REPORT:
2366
+					case DIGEST:
2367
+					case APPLEDOUBLE:
2368
+					case KNOWBOT:
2369
+					case -1:
2370
+						mainMessage = do_multipart(mainMessage,
2371
+							messages, multiparts,
2372
+							&rc, mctx, messageIn,
2373
+							&aText);
2374
+						--multiparts;
2375
+						if(rc == 3)
2376
+							infected = TRUE;
2377
+						break;
2378
+					default:
2379
+						messageClean(aMessage);
2380
+				}
2357 2381
 			}
2358 2382
 
2359 2383
 			free((char *)boundary);
... ...
@@ -2362,7 +2394,7 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
2362 2362
 			 * Preprocess. Anything special to be done before
2363 2363
 			 * we handle the multiparts?
2364 2364
 			 */
2365
-			switch(tableFind(mctx->subtypeTable, mimeSubtype)) {
2365
+			switch(subtype) {
2366 2366
 				case KNOWBOT:
2367 2367
 					/* TODO */
2368 2368
 					cli_dbgmsg("multipart/knowbot parsed as multipart/mixed for now\n");
... ...
@@ -2387,13 +2419,18 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
2387 2387
 				mainMessage = NULL;
2388 2388
 			}
2389 2389
 
2390
-			if(multiparts == 0) {
2390
+			cli_dbgmsg("The message has %d parts\n", multiparts);
2391
+
2392
+			if(((multiparts == 0) || infected) && (aText == NULL)) {
2391 2393
 				if(messages)
2392 2394
 					free(messages);
2393
-				return 2;	/* Nothing to do */
2395
+				/*
2396
+				 * FIXME: we could return 2 here when we have
2397
+				 * saved stuff earlier
2398
+				 */
2399
+				return (rc == 3) ? 3 : 2;	/* Nothing to do */
2394 2400
 			}
2395 2401
 
2396
-			cli_dbgmsg("The message has %d parts\n", multiparts);
2397 2402
 			cli_dbgmsg("Find out the multipart type (%s)\n", mimeSubtype);
2398 2403
 
2399 2404
 			/*