Browse code

Added destroy flag

git-svn: trunk@2058

Nigel Horne authored on 2006/07/02 01:21:03
Showing 8 changed files
... ...
@@ -1,3 +1,7 @@
1
+Sat Jul  1 17:18:17 BST 2006 (njh)
2
+----------------------------------
3
+  * libclamav:	Free memory earlier
4
+
1 5
 Sat Jul  1 04:49:32 BST 2006 (njh)
2 6
 ----------------------------------
3 7
   * libclamav:	Large binhex files were not being handled gracefully. Tidied
... ...
@@ -18,6 +18,9 @@
18 18
  *
19 19
  * Change History:
20 20
  * $Log: binhex.c,v $
21
+ * Revision 1.21  2006/07/01 16:17:35  njh
22
+ * Added destroy flag
23
+ *
21 24
  * Revision 1.20  2006/07/01 03:47:50  njh
22 25
  * Don't loop if binhex runs out of memory
23 26
  *
... ...
@@ -76,7 +79,7 @@
76 76
  * First draft of binhex.c
77 77
  *
78 78
  */
79
-static	char	const	rcsid[] = "$Id: binhex.c,v 1.20 2006/07/01 03:47:50 njh Exp $";
79
+static	char	const	rcsid[] = "$Id: binhex.c,v 1.21 2006/07/01 16:17:35 njh Exp $";
80 80
 
81 81
 #include "clamav.h"
82 82
 
... ...
@@ -195,7 +198,7 @@ cli_binhex(const char *dir, int desc)
195 195
 	/* similar to binhexMessage */
196 196
 	messageSetEncoding(m, "x-binhex");
197 197
 
198
-	fb = messageToFileblob(m, dir);
198
+	fb = messageToFileblob(m, dir, 1);
199 199
 	if(fb) {
200 200
 		cli_dbgmsg("Binhex file decoded to %s\n", fileblobGetFilename(fb));
201 201
 		fileblobDestroy(fb);
... ...
@@ -205,6 +208,6 @@ cli_binhex(const char *dir, int desc)
205 205
 
206 206
 	if(fb)
207 207
 		return CL_CLEAN;	/* a lie - but it gets things going */
208
-	return CL_EIO;
208
+	return CL_EIO;	/* probably CL_EMEM, but we can't tell at this layer */
209 209
 #endif
210 210
 }
... ...
@@ -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: blob.c,v 1.50 2006/07/01 03:47:50 njh Exp $";
19
+static	char	const	rcsid[] = "$Id: blob.c,v 1.51 2006/07/01 16:17:35 njh Exp $";
20 20
 
21 21
 #if HAVE_CONFIG_H
22 22
 #include "clamav-config.h"
... ...
@@ -172,7 +172,8 @@ blobAddData(blob *b, const unsigned char *data, size_t len)
172 172
 	if(len >= (size_t)pagesize)
173 173
 		growth = ((len / pagesize) + 1) * pagesize;
174 174
 
175
-	/*printf("len %u, growth = %u\n", len, growth);*/
175
+	/*cli_dbgmsg("blobGrow: b->size %lu, b->len %lu, len %lu, growth = %u\n",
176
+		b->size, b->len, len, growth);*/
176 177
 
177 178
 	if(b->data == NULL) {
178 179
 		assert(b->len == 0);
... ...
@@ -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.313 2006/06/28 21:07:36 njh Exp $";
19
+static	char	const	rcsid[] = "$Id: mbox.c,v 1.314 2006/07/01 16:17:35 njh Exp $";
20 20
 
21 21
 #if HAVE_CONFIG_H
22 22
 #include "clamav-config.h"
... ...
@@ -196,7 +196,7 @@ typedef	struct	mbox_ctx {
196 196
 
197 197
 static	int	cli_parse_mbox(const char *dir, int desc, cli_ctx *ctx);
198 198
 static	message	*parseEmailFile(FILE *fin, const table_t *rfc821Table, const char *firstLine, const char *dir);
199
-static	message	*parseEmailHeaders(const message *m, const table_t *rfc821Table);
199
+static	message	*parseEmailHeaders(message *m, const table_t *rfc821Table);
200 200
 static	int	parseEmailHeader(message *m, const char *line, const table_t *rfc821Table);
201 201
 static	int	parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx);
202 202
 static	int	boundaryStart(const char *line, const char *boundary);
... ...
@@ -215,7 +215,7 @@ static	int	rfc1341(message *m, const char *dir);
215 215
 static	bool	usefulHeader(int commandNumber, const char *cmd);
216 216
 static	char	*getline_from_mbox(char *buffer, size_t len, FILE *fin);
217 217
 static	bool	isBounceStart(const char *line);
218
-static	bool	binhexMessage(const char *dir, message *message);
218
+static	bool	binhexMessage(const char *dir, message *m);
219 219
 static	message	*do_multipart(message *mainMessage, message **messages, int i, int *rc, mbox_ctx *mctx, message *messageIn, text **tptr);
220 220
 
221 221
 static	void	checkURLs(message *m, const char *dir);
... ...
@@ -908,7 +908,7 @@ cli_mbox(const char *dir, int desc, cli_ctx *ctx)
908 908
 				} while(quotedsize > 0L);
909 909
 
910 910
 				free(line);
911
-				fb = messageToFileblob(m, dir);
911
+				fb = messageToFileblob(m, dir, 1);
912 912
 				messageDestroy(m);
913 913
 
914 914
 				if(fb)
... ...
@@ -1676,7 +1676,7 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch
1676 1676
  * TODO: remove the duplication with parseEmailFile
1677 1677
  */
1678 1678
 static message *
1679
-parseEmailHeaders(const message *m, const table_t *rfc821)
1679
+parseEmailHeaders(message *m, const table_t *rfc821)
1680 1680
 {
1681 1681
 	bool inHeader = TRUE;
1682 1682
 	bool bodyIsEmpty = TRUE;
... ...
@@ -1937,28 +1937,25 @@ parseEmailHeader(message *m, const char *line, const table_t *rfc821)
1937 1937
 static int	/* success or fail */
1938 1938
 parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
1939 1939
 {
1940
-	message **messages;	/* parts of a multipart message */
1941
-	int inMimeHead, i, rc = 1, htmltextPart, multiparts = 0;
1942
-	text *aText;
1943
-	message *mainMessage;
1940
+	int rc = 1;
1941
+	text *aText = textIn;
1942
+	message *mainMessage = messageIn;
1944 1943
 	fileblob *fb;
1945 1944
 	bool infected = FALSE;
1946 1945
 
1947 1946
 	cli_dbgmsg("in parseEmailBody\n");
1948 1947
 
1949
-	aText = textIn;
1950
-	messages = NULL;
1951
-	mainMessage = messageIn;
1952
-
1953 1948
 	/* Anything left to be parsed? */
1954 1949
 	if(mainMessage && (messageGetBody(mainMessage) != NULL)) {
1955 1950
 		mime_type mimeType;
1956
-		int subtype, inhead;
1951
+		int subtype, inhead, htmltextPart, inMimeHead, i;
1957 1952
 		const char *mimeSubtype, *boundary;
1958 1953
 		char *protocol;
1959 1954
 		const text *t_line;
1960 1955
 		/*bool isAlternative;*/
1961 1956
 		message *aMessage;
1957
+		int multiparts = 0;
1958
+		message **messages = NULL;	/* parts of a multipart message */
1962 1959
 
1963 1960
 		cli_dbgmsg("Parsing mail file\n");
1964 1961
 
... ...
@@ -2565,7 +2562,7 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
2565 2565
 					fileblobSetFilename(fb, mctx->dir, "textpart");
2566 2566
 					/*fileblobAddData(fb, "Received: by clamd (textpart)\n", 30);*/
2567 2567
 					fileblobSetCTX(fb, mctx->ctx);
2568
-					(void)textToFileblob(aText, fb);
2568
+					(void)textToFileblob(aText, fb, 0);
2569 2569
 
2570 2570
 					fileblobDestroy(fb);
2571 2571
 				}
... ...
@@ -2646,7 +2643,7 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
2646 2646
 			if((strcasecmp(cptr, "octet-stream") == 0) ||
2647 2647
 			   (strcasecmp(cptr, "x-msdownload") == 0)) {*/
2648 2648
 			{
2649
-				fb = messageToFileblob(mainMessage, mctx->dir);
2649
+				fb = messageToFileblob(mainMessage, mctx->dir, 1);
2650 2650
 
2651 2651
 				if(fb) {
2652 2652
 					cli_dbgmsg("Saving main message as attachment\n");
... ...
@@ -2670,6 +2667,9 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
2670 2670
 			cli_warnmsg("Message received with unknown mime encoding");
2671 2671
 			break;
2672 2672
 		}
2673
+
2674
+		if(messages)
2675
+			free(messages);
2673 2676
 	}
2674 2677
 
2675 2678
 	if(aText && (textIn == NULL)) {
... ...
@@ -2800,26 +2800,16 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
2800 2800
 	 * No attachments - scan the text portions, often files
2801 2801
 	 * are hidden in HTML code
2802 2802
 	 */
2803
-	cli_dbgmsg("%d multiparts found\n", multiparts);
2804
-	for(i = 0; i < multiparts; i++) {
2805
-		fb = messageToFileblob(messages[i], mctx->dir);
2806
-
2807
-		if(fb) {
2808
-			cli_dbgmsg("Saving multipart %d\n", i);
2809
-
2810
-			fileblobDestroy(fb);
2811
-		}
2812
-	}
2813
-
2814 2803
 	if(mainMessage && (rc != 3)) {
2815 2804
 		/*
2816 2805
 		 * Look for uu-encoded main file
2817 2806
 		 */
2818
-		const text *t_line;
2807
+		text *t_line;
2819 2808
 
2820 2809
 		if((encodingLine(mainMessage) != NULL) &&
2821 2810
 			  ((t_line = bounceBegin(mainMessage)) != NULL)) {
2822
-			const text *t, *start;
2811
+			text *t, *start;
2812
+
2823 2813
 			/*
2824 2814
 			 * Attempt to save the original (unbounced)
2825 2815
 			 * message - clamscan will find that in the
... ...
@@ -2873,7 +2863,7 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
2873 2873
 				cli_dbgmsg("Found a bounce message\n");
2874 2874
 				fileblobSetFilename(fb, mctx->dir, "bounce");
2875 2875
 				/*fileblobSetCTX(fb, ctx);*/
2876
-				if(textToFileblob(start, fb) == NULL)
2876
+				if(textToFileblob(start, fb, 0) == NULL)
2877 2877
 					cli_dbgmsg("Nothing new to save in the bounce message\n");
2878 2878
 				else
2879 2879
 					rc = 1;
... ...
@@ -2908,20 +2898,18 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
2908 2908
 						28);
2909 2909
 
2910 2910
 					/*fileblobSetCTX(fb, ctx);*/
2911
-					fb = textToFileblob(t_line, fb);
2911
+					fb = textToFileblob(t_line, fb, 0);
2912 2912
 
2913 2913
 					fileblobDestroy(fb);
2914 2914
 				}
2915 2915
 				saveIt = FALSE;
2916
-			} else if(multiparts == 0)
2916
+			} else
2917 2917
 				/*
2918 2918
 				 * Save the entire text portion,
2919 2919
 				 * since it it may be an HTML file with
2920 2920
 				 * a JavaScript virus or a phish
2921 2921
 				 */
2922 2922
 				saveIt = TRUE;
2923
-			else
2924
-				saveIt = FALSE;
2925 2923
 
2926 2924
 			if(saveIt) {
2927 2925
 				cli_dbgmsg("Saving text part to scan\n");
... ...
@@ -2938,14 +2926,11 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
2938 2938
 			}
2939 2939
 		}
2940 2940
 	} else
2941
-		rc = (multiparts) ? 1 : 2;	/* anything saved? */
2941
+		rc = 2;	/* nothing saved */
2942 2942
 
2943 2943
 	if(mainMessage && (mainMessage != messageIn))
2944 2944
 		messageDestroy(mainMessage);
2945 2945
 
2946
-	if(messages)
2947
-		free(messages);
2948
-
2949 2946
 	if((rc != 0) && infected)
2950 2947
 		rc = 3;
2951 2948
 
... ...
@@ -3411,7 +3396,7 @@ saveTextPart(message *m, const char *dir)
3411 3411
 	fileblob *fb;
3412 3412
 
3413 3413
 	messageAddArgument(m, "filename=textportion");
3414
-	if((fb = messageToFileblob(m, dir)) != NULL) {
3414
+	if((fb = messageToFileblob(m, dir, 0)) != NULL) {
3415 3415
 		/*
3416 3416
 		 * Save main part to scan that
3417 3417
 		 */
... ...
@@ -3581,7 +3566,7 @@ rfc2047(const char *in)
3581 3581
 				messageSetEncoding(m, "base64");
3582 3582
 				break;
3583 3583
 		}
3584
-		b = messageToBlob(m);
3584
+		b = messageToBlob(m, 1);
3585 3585
 		len = blobGetDataSize(b);
3586 3586
 		cli_dbgmsg("Decoded as '%*.*s'\n", len, len, blobGetData(b));
3587 3587
 		memcpy(pout, blobGetData(b), len);
... ...
@@ -3673,7 +3658,7 @@ rfc1341(message *m, const char *dir)
3673 3673
 		free(oldfilename);
3674 3674
 	}
3675 3675
 
3676
-	if((fb = messageToFileblob(m, pdir)) == NULL) {
3676
+	if((fb = messageToFileblob(m, pdir, 0)) == NULL) {
3677 3677
 		free(id);
3678 3678
 		free(number);
3679 3679
 		return -1;
... ...
@@ -3805,7 +3790,7 @@ rfc1341(message *m, const char *dir)
3805 3805
 static void
3806 3806
 checkURLs(message *m, const char *dir)
3807 3807
 {
3808
-	blob *b = messageToBlob(m);
3808
+	blob *b = messageToBlob(m, 0);
3809 3809
 	size_t len;
3810 3810
 	table_t *t;
3811 3811
 	int i, n;
... ...
@@ -4294,7 +4279,7 @@ binhexMessage(const char *dir, message *m)
4294 4294
 	if(messageGetEncoding(m) == NOENCODING)
4295 4295
 		messageSetEncoding(m, "x-binhex");
4296 4296
 
4297
-	fb = messageToFileblob(m, dir);
4297
+	fb = messageToFileblob(m, dir, 0);
4298 4298
 
4299 4299
 	if(fb) {
4300 4300
 		if(fileblobContainsVirus(fb))
... ...
@@ -4518,7 +4503,7 @@ do_multipart(message *mainMessage, message **messages, int i, int *rc, mbox_ctx
4518 4518
 		cli_dbgmsg("Adding to non mime-part\n");
4519 4519
 		*tptr = textAdd(*tptr, messageGetBody(aMessage));
4520 4520
 	} else {
4521
-		fileblob *fb = messageToFileblob(aMessage, mctx->dir);
4521
+		fileblob *fb = messageToFileblob(aMessage, mctx->dir, 1);
4522 4522
 
4523 4523
 		if(fb) {
4524 4524
 			if(fileblobContainsVirus(fb))
... ...
@@ -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: message.c,v 1.176 2006/07/01 03:47:50 njh Exp $";
19
+static	char	const	rcsid[] = "$Id: message.c,v 1.177 2006/07/01 16:17:35 njh Exp $";
20 20
 
21 21
 #if HAVE_CONFIG_H
22 22
 #include "clamav-config.h"
... ...
@@ -78,7 +78,7 @@ static	const	char	*messageGetArgument(const message *m, int arg);
78 78
 /*
79 79
  * http://oopweb.com/CPP/Documents/FunctionPointers/Volume/CCPP/callback/callback.html
80 80
  */
81
-static	void	*messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy)(void *), void (*setFilename)(void *, const char *, const char *), void (*addData)(void *, const unsigned char *, size_t), void *(*exportText)(const text *, void *), void (*setCTX)(void *, cli_ctx *));
81
+static	void	*messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy)(void *), void (*setFilename)(void *, const char *, const char *), void (*addData)(void *, const unsigned char *, size_t), void *(*exportText)(text *, void *, int), void (*setCTX)(void *, cli_ctx *), int destroy_text);
82 82
 static	int	usefulArg(const char *arg);
83 83
 static	void	messageDedup(message *m);
84 84
 static	char	*rfc2231(const char *in);
... ...
@@ -983,8 +983,8 @@ messageIsEncoding(message *m)
983 983
  * Returns a pointer to the body of the message. Note that it does NOT return
984 984
  * a copy of the data
985 985
  */
986
-const text *
987
-messageGetBody(const message *m)
986
+text *
987
+messageGetBody(message *m)
988 988
 {
989 989
 	assert(m != NULL);
990 990
 	return m->body_first;
... ...
@@ -1010,10 +1010,10 @@ messageClean(message *m)
1010 1010
  * last item that was exported. That's sufficient for now.
1011 1011
  */
1012 1012
 static void *
1013
-messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy)(void *), void (*setFilename)(void *, const char *, const char *), void (*addData)(void *, const unsigned char *, size_t), void *(*exportText)(const text *, void *), void(*setCTX)(void *, cli_ctx *))
1013
+messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy)(void *), void (*setFilename)(void *, const char *, const char *), void (*addData)(void *, const unsigned char *, size_t), void *(*exportText)(text *, void *, int), void(*setCTX)(void *, cli_ctx *), int destroy_text)
1014 1014
 {
1015 1015
 	void *ret;
1016
-	const text *t_line;
1016
+	text *t_line;
1017 1017
 	char *filename;
1018 1018
 	int i;
1019 1019
 
... ...
@@ -1069,8 +1069,17 @@ messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy
1069 1069
 		      (t_line->t_line == NULL))
1070 1070
 			;
1071 1071
 
1072
-		tmp = textToBlob(t_line, NULL);
1072
+		tmp = textToBlob(t_line, NULL,
1073
+			((m->numberOfEncTypes == 1) && (m->encodingTypes[0] == BINHEX)) ? destroy_text : 0);
1074
+
1073 1075
 		if(tmp == NULL) {
1076
+			/*
1077
+			 * FIXME: We've probably run out of memory during the
1078
+			 * text to blob.
1079
+			 * TODO: if m->numberOfEncTypes == 1 we could delete
1080
+			 * the text object as we decode it
1081
+			 */
1082
+			cli_warnmsg("Couldn't start binhex parser\n");
1074 1083
 			(*destroy)(ret);
1075 1084
 			return NULL;
1076 1085
 		}
... ...
@@ -1334,7 +1343,7 @@ messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy
1334 1334
 			free((char *)filename);
1335 1335
 
1336 1336
 		if(m->numberOfEncTypes == 0)
1337
-			return exportText(messageGetBody(m), ret);
1337
+			return exportText(messageGetBody(m), ret, destroy_text);
1338 1338
 	}
1339 1339
 
1340 1340
 	if(setCTX && m->ctx)
... ...
@@ -1432,7 +1441,12 @@ messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy
1432 1432
 			/*
1433 1433
 			 * Fast copy
1434 1434
 			 */
1435
-			(void)exportText(t_line, ret);
1435
+			if(i == m->numberOfEncTypes - 1) {
1436
+				/* last one */
1437
+				(void)exportText(t_line, ret, destroy_text);
1438
+				break;
1439
+			}
1440
+			(void)exportText(t_line, ret, 0);
1436 1441
 			continue;
1437 1442
 		}
1438 1443
 
... ...
@@ -1529,10 +1543,17 @@ base64Flush(message *m, unsigned char *buf)
1529 1529
  * The caller must free the returned fileblob
1530 1530
  */
1531 1531
 fileblob *
1532
-messageToFileblob(message *m, const char *dir)
1532
+messageToFileblob(message *m, const char *dir, int destroy)
1533 1533
 {
1534
+	fileblob *fb;
1535
+
1534 1536
 	cli_dbgmsg("messageToFileblob\n");
1535
-	return messageExport(m, dir, (void *)fileblobCreate, (void *)fileblobDestroy, (void *)fileblobSetFilename, (void *)fileblobAddData, (void *)textToFileblob, (void *)fileblobSetCTX);
1537
+	fb = messageExport(m, dir, (void *)fileblobCreate, (void *)fileblobDestroy, (void *)fileblobSetFilename, (void *)fileblobAddData, (void *)textToFileblob, (void *)fileblobSetCTX, destroy);
1538
+	if(destroy && m->body_first) {
1539
+		textDestroy(m->body_first);
1540
+		m->body_first = m->body_last = NULL;
1541
+	}
1542
+	return fb;
1536 1543
 }
1537 1544
 
1538 1545
 /*
... ...
@@ -1540,9 +1561,15 @@ messageToFileblob(message *m, const char *dir)
1540 1540
  * The caller must free the returned blob
1541 1541
  */
1542 1542
 blob *
1543
-messageToBlob(message *m)
1543
+messageToBlob(message *m, int destroy)
1544 1544
 {
1545
-	return messageExport(m, NULL, (void *)blobCreate, (void *)blobDestroy, (void *)blobSetFilename, (void *)blobAddData, (void *)textToBlob, NULL);
1545
+	blob *b = messageExport(m, NULL, (void *)blobCreate, (void *)blobDestroy, (void *)blobSetFilename, (void *)blobAddData, (void *)textToBlob, NULL, destroy);
1546
+
1547
+	if(destroy && m->body_first) {
1548
+		textDestroy(m->body_first);
1549
+		m->body_first = m->body_last = NULL;
1550
+	}
1551
+	return b;
1546 1552
 }
1547 1553
 
1548 1554
 /*
... ...
@@ -1728,8 +1755,8 @@ messageToText(message *m)
1728 1728
 	return first;
1729 1729
 }
1730 1730
 
1731
-const text *
1732
-yEncBegin(const message *m)
1731
+text *
1732
+yEncBegin(message *m)
1733 1733
 {
1734 1734
 	return m->yenc;
1735 1735
 }
... ...
@@ -1738,8 +1765,8 @@ yEncBegin(const message *m)
1738 1738
  * Scan to find the BINHEX message (if any)
1739 1739
  */
1740 1740
 #if	0
1741
-static const text *
1742
-binhexBegin(const message *m)
1741
+const text *
1742
+binhexBegin(message *m)
1743 1743
 {
1744 1744
 	const text *t_line;
1745 1745
 
... ...
@@ -1750,8 +1777,8 @@ binhexBegin(const message *m)
1750 1750
 	return NULL;
1751 1751
 }
1752 1752
 #else
1753
-const text *
1754
-binhexBegin(const message *m)
1753
+text *
1754
+binhexBegin(message *m)
1755 1755
 {
1756 1756
 	return m->binhex;
1757 1757
 }
... ...
@@ -1762,8 +1789,8 @@ binhexBegin(const message *m)
1762 1762
  * even a convention, so don't expect this to be foolproof
1763 1763
  */
1764 1764
 #if	0
1765
-const text *
1766
-bounceBegin(const message *m)
1765
+text *
1766
+bounceBegin(message *m)
1767 1767
 {
1768 1768
 	const text *t_line;
1769 1769
 
... ...
@@ -1774,8 +1801,8 @@ bounceBegin(const message *m)
1774 1774
 	return NULL;
1775 1775
 }
1776 1776
 #else
1777
-const text *
1778
-bounceBegin(const message *m)
1777
+text *
1778
+bounceBegin(message *m)
1779 1779
 {
1780 1780
 	return m->bounce;
1781 1781
 }
... ...
@@ -1806,8 +1833,8 @@ messageIsAllText(const message *m)
1806 1806
 	return 1;
1807 1807
 }
1808 1808
 #else
1809
-const text *
1810
-encodingLine(const message *m)
1809
+text *
1810
+encodingLine(message *m)
1811 1811
 {
1812 1812
 	return m->encoding;
1813 1813
 }
... ...
@@ -39,10 +39,10 @@ typedef struct message {
39 39
 	 * Markers for the start of various non MIME messages that could
40 40
 	 * be included within this message
41 41
 	 */
42
-	const text	*bounce;	/* start of a bounced message */
43
-	const text	*binhex;	/* start of a binhex message */
44
-	const text	*yenc;		/* start of a yEnc message */
45
-	const text	*encoding;	/* is the non MIME message encoded? */
42
+	text	*bounce;	/* start of a bounced message */
43
+	text	*binhex;	/* start of a binhex message */
44
+	text	*yenc;		/* start of a yEnc message */
45
+	text	*encoding;	/* is the non MIME message encoded? */
46 46
 	const text	*dedupedThisFar;
47 47
 } message;
48 48
 
... ...
@@ -63,16 +63,16 @@ encoding_type	messageGetEncoding(const message *m);
63 63
 int	messageAddLine(message *m, line_t *line);
64 64
 int	messageAddStr(message *m, const char *data);
65 65
 int	messageAddStrAtTop(message *m, const char *data);
66
-const	text	*messageGetBody(const message *m);
66
+text	*messageGetBody(message *m);
67 67
 void	messageClean(message *m);
68 68
 unsigned	char	*base64Flush(message *m, unsigned char *buf);
69
-fileblob	*messageToFileblob(message *m, const char *dir);
70
-blob	*messageToBlob(message *m);
69
+fileblob	*messageToFileblob(message *m, const char *dir, int destroy);
70
+blob	*messageToBlob(message *m, int destroy);
71 71
 text	*messageToText(message *m);
72
-const	text	*binhexBegin(const message *m);
73
-const	text	*yEncBegin(const message *m);
74
-const	text	*bounceBegin(const message *m);
75
-const	text	*encodingLine(const message *m);
72
+text	*binhexBegin(message *m);
73
+text	*yEncBegin(message *m);
74
+text	*bounceBegin(message *m);
75
+text	*encodingLine(message *m);
76 76
 void	messageClearMarkers(message *m);
77 77
 unsigned char	*decodeLine(message *m, encoding_type enctype, const char *line, unsigned char *buf, size_t buflen);
78 78
 int	isuuencodebegin(const char *line);
... ...
@@ -17,6 +17,9 @@
17 17
  *  MA 02110-1301, USA.
18 18
  *
19 19
  * $Log: text.c,v $
20
+ * Revision 1.21  2006/07/01 16:17:35  njh
21
+ * Added destroy flag
22
+ *
20 23
  * Revision 1.20  2006/07/01 03:47:50  njh
21 24
  * Don't loop if binhex runs out of memory
22 25
  *
... ...
@@ -70,7 +73,7 @@
70 70
  *
71 71
  */
72 72
 
73
-static	char	const	rcsid[] = "$Id: text.c,v 1.20 2006/07/01 03:47:50 njh Exp $";
73
+static	char	const	rcsid[] = "$Id: text.c,v 1.21 2006/07/01 16:17:35 njh Exp $";
74 74
 
75 75
 #if HAVE_CONFIG_H
76 76
 #include "clamav-config.h"
... ...
@@ -104,7 +107,7 @@ static	text	*textCopy(const text *t_head);
104 104
 static	void	addToFileblob(const line_t *line, void *arg);
105 105
 static	void	getLength(const line_t *line, void *arg);
106 106
 static	void	addToBlob(const line_t *line, void *arg);
107
-static	void	*textIterate(const text *t_text, void (*cb)(const line_t *line, void *arg), void *arg);
107
+static	void	*textIterate(text *t_text, void (*cb)(const line_t *line, void *arg), void *arg, int destroy);
108 108
 
109 109
 void
110 110
 textDestroy(text *t_head)
... ...
@@ -233,7 +236,7 @@ textAddMessage(text *aText, message *aMessage)
233 233
  * The caller must free the returned blob if b is NULL
234 234
  */
235 235
 blob *
236
-textToBlob(const text *t, blob *b)
236
+textToBlob(text *t, blob *b, int destroy)
237 237
 {
238 238
 	size_t s;
239 239
 	blob *bin;
... ...
@@ -243,11 +246,16 @@ textToBlob(const text *t, blob *b)
243 243
 
244 244
 	s = 0;
245 245
 
246
-	(void)textIterate(t, getLength, &s);
246
+	(void)textIterate(t, getLength, &s, 0);
247 247
 
248 248
 	if(s == 0)
249 249
 		return b;
250 250
 
251
+	/*
252
+	 * copy b. If b is NULL and an error occurs we know we need to free
253
+	 *	before returning
254
+	 */
255
+	bin = b;
251 256
 	if(b == NULL) {
252 257
 		b = blobCreate();
253 258
 
... ...
@@ -255,14 +263,26 @@ textToBlob(const text *t, blob *b)
255 255
 			return NULL;
256 256
 	}
257 257
 
258
-	bin = b;
259 258
 	if(blobGrow(b, s) != CL_SUCCESS) {
259
+		cli_warnmsg("Couldn't grow the blob we may be low on memory\n");
260
+#if	0
261
+		if(!destroy) {
262
+			if(bin == NULL)
263
+				blobDestroy(b);
264
+			return NULL;
265
+		}
266
+		/*
267
+		 * We may be able to recover enough memory as we destroy to
268
+		 * create the blob
269
+		 */
270
+#else
260 271
 		if(bin == NULL)
261 272
 			blobDestroy(b);
262 273
 		return NULL;
274
+#endif
263 275
 	}
264 276
 
265
-	(void)textIterate(t, addToBlob, b);
277
+	(void)textIterate(t, addToBlob, b, destroy);
266 278
 
267 279
 	blobClose(b);
268 280
 
... ...
@@ -270,7 +290,7 @@ textToBlob(const text *t, blob *b)
270 270
 }
271 271
 
272 272
 fileblob *
273
-textToFileblob(const text *t, fileblob *fb)
273
+textToFileblob(text *t, fileblob *fb, int destroy)
274 274
 {
275 275
 	assert(fb != NULL);
276 276
 	assert(t != NULL);
... ...
@@ -283,7 +303,7 @@ textToFileblob(const text *t, fileblob *fb)
283 283
 	} else
284 284
 		fb->ctx = NULL;	/* no need to scan */
285 285
 
286
-	return textIterate(t, addToFileblob, fb);
286
+	return textIterate(t, addToFileblob, fb, destroy);
287 287
 }
288 288
 
289 289
 static void
... ...
@@ -324,10 +344,16 @@ addToFileblob(const line_t *line, void *arg)
324 324
 }
325 325
 
326 326
 static void *
327
-textIterate(const text *t_text, void (*cb)(const line_t *item, void *arg), void *arg)
327
+textIterate(text *t_text, void (*cb)(const line_t *item, void *arg), void *arg, int destroy)
328 328
 {
329 329
 	while(t_text) {
330 330
 		(*cb)(t_text->t_line, arg);
331
+
332
+		if(destroy && t_text->t_line) {
333
+			lineUnlink(t_text->t_line);
334
+			t_text->t_line = NULL;
335
+		}
336
+
331 337
 		t_text = t_text->t_next;
332 338
 	}
333 339
 	return arg;
... ...
@@ -17,6 +17,9 @@
17 17
  *  MA 02110-1301, USA.
18 18
  *
19 19
  * $Log: text.h,v $
20
+ * Revision 1.9  2006/07/01 16:17:35  njh
21
+ * Added destroy flag
22
+ *
20 23
  * Revision 1.8  2006/04/09 19:59:28  kojm
21 24
  * update GPL headers with new address for FSF
22 25
  *
... ...
@@ -48,5 +51,5 @@ void	textDestroy(text *t_head);
48 48
 text	*textClean(text *t_head);
49 49
 text	*textAdd(text *t_head, const text *t);
50 50
 text	*textAddMessage(text *aText, message *aMessage);
51
-blob	*textToBlob(const text *t, blob *b);
52
-fileblob	*textToFileblob(const text *t, fileblob *fb);
51
+blob	*textToBlob(text *t, blob *b, int destroy);
52
+fileblob	*textToFileblob(text *t, fileblob *fb, int destroy);