Browse code

Various code clean ups and optimisations

git-svn: trunk@3212

Nigel Horne authored on 2007/09/11 19:22:49
Showing 6 changed files
... ...
@@ -1,3 +1,7 @@
1
+Tue Sep 11 10:33:21 BST 2007 (njh)
2
+----------------------------------
3
+  * libclamav:	Various code clean ups and optimisations
4
+
1 5
 Sun Sep  9 13:42:26 CEST 2007 (acab)
2 6
   * libclamav/nsis: tidy
3 7
 
... ...
@@ -653,9 +653,9 @@ fileblobScan(const fileblob *fb)
653 653
 #ifndef	C_WINDOWS
654 654
 	/*
655 655
 	 * FIXME: On Windows, cli_readn gives "bad file descriptor" when called
656
-	 * by cli_check_mydoom_log from a call do cli_magic_scandesc here which
657
-	 * implies that the file descriptor is getting closed somewhere, but I
658
-	 * can't see where.
656
+	 * by cli_check_mydoom_log from the call to cli_magic_scandesc here
657
+	 * which implies that the file descriptor is getting closed somewhere,
658
+	 * but I can't see where.
659 659
 	 * One possible fix would be to duplicate cli_scanfile here.
660 660
 	 */
661 661
 	fflush(fb->fp);
... ...
@@ -3255,10 +3255,13 @@ strstrip(char *s)
3255 3255
 	return(strip(s, (int)strlen(s) + 1));
3256 3256
 }
3257 3257
 
3258
+/*
3259
+ * Returns 0 for OK, -1 for error
3260
+ */
3258 3261
 static int
3259 3262
 parseMimeHeader(message *m, const char *cmd, const table_t *rfc821Table, const char *arg)
3260 3263
 {
3261
-	char *copy, *p;
3264
+	char *copy, *p, *buf;
3262 3265
 	const char *ptr;
3263 3266
 	int commandNumber;
3264 3267
 
... ...
@@ -3278,6 +3281,8 @@ parseMimeHeader(message *m, const char *cmd, const table_t *rfc821Table, const c
3278 3278
 	else
3279 3279
 		ptr = arg;
3280 3280
 
3281
+	buf = NULL;
3282
+
3281 3283
 	switch(commandNumber) {
3282 3284
 		case CONTENT_TYPE:
3283 3285
 			/*
... ...
@@ -3309,6 +3314,12 @@ parseMimeHeader(message *m, const char *cmd, const table_t *rfc821Table, const c
3309 3309
 				int i;
3310 3310
 				char *mimeArgs;	/* RHS of the ; */
3311 3311
 
3312
+				buf = cli_malloc(strlen(ptr) + 1);
3313
+				if(buf == NULL) {
3314
+					if(copy)
3315
+						free(copy);
3316
+					return -1;
3317
+				}
3312 3318
 				/*
3313 3319
 				 * Some clients are broken and
3314 3320
 				 * put white space after the ;
... ...
@@ -3332,12 +3343,11 @@ parseMimeHeader(message *m, const char *cmd, const table_t *rfc821Table, const c
3332 3332
 
3333 3333
 					if(ptr[0] != '/') {
3334 3334
 						char *s;
3335
-						char *mimeType;	/* LHS of the ; */
3336 3335
 #ifdef CL_THREAD_SAFE
3337 3336
 						char *strptr = NULL;
3338 3337
 #endif
3339 3338
 
3340
-						s = mimeType = cli_strtok(ptr, 0, ";");
3339
+						s = cli_strtokbuf(ptr, 0, ";", buf);
3341 3340
 						/*
3342 3341
 						 * Handle
3343 3342
 						 * Content-Type: foo/bar multipart/mixed
... ...
@@ -3371,12 +3381,10 @@ parseMimeHeader(message *m, const char *cmd, const table_t *rfc821Table, const c
3371 3371
 									len = strstrip(s);
3372 3372
 								}
3373 3373
 								if(len) {
3374
-									if(strchr(s, ' ')) {
3375
-										char *t = cli_strtok(s, 0, " ");
3376
-
3377
-										messageSetMimeSubtype(m, t);
3378
-										free(t);
3379
-									} else
3374
+									if(strchr(s, ' '))
3375
+										messageSetMimeSubtype(m,
3376
+											cli_strtokbuf(s, 0, " ", buf));
3377
+									else
3380 3378
 										messageSetMimeSubtype(m, s);
3381 3379
 								}
3382 3380
 							}
... ...
@@ -3388,8 +3396,6 @@ parseMimeHeader(message *m, const char *cmd, const table_t *rfc821Table, const c
3388 3388
 							if(*s == '\0')
3389 3389
 								break;
3390 3390
 						}
3391
-						if(mimeType)
3392
-							free(mimeType);
3393 3391
 					}
3394 3392
 				}
3395 3393
 
... ...
@@ -3400,11 +3406,10 @@ parseMimeHeader(message *m, const char *cmd, const table_t *rfc821Table, const c
3400 3400
 				 * we find the boundary argument set it
3401 3401
 				 */
3402 3402
 				i = 1;
3403
-				while((mimeArgs = cli_strtok(ptr, i++, ";")) != NULL) {
3403
+				while((mimeArgs = cli_strtokbuf(ptr, i++, ";", buf)) != NULL) {
3404 3404
 					cli_dbgmsg("mimeArgs = '%s'\n", mimeArgs);
3405 3405
 
3406 3406
 					messageAddArguments(m, mimeArgs);
3407
-					free(mimeArgs);
3408 3407
 				}
3409 3408
 			}
3410 3409
 			break;
... ...
@@ -3412,15 +3417,18 @@ parseMimeHeader(message *m, const char *cmd, const table_t *rfc821Table, const c
3412 3412
 			messageSetEncoding(m, ptr);
3413 3413
 			break;
3414 3414
 		case CONTENT_DISPOSITION:
3415
-			p = cli_strtok(ptr, 0, ";");
3415
+			buf = cli_malloc(strlen(ptr) + 1);
3416
+			if(buf == NULL) {
3417
+				if(copy)
3418
+					free(copy);
3419
+				return -1;
3420
+			}
3421
+			p = cli_strtokbuf(ptr, 0, ";", buf);
3416 3422
 			if(p) {
3417 3423
 				if(*p) {
3418 3424
 					messageSetDispositionType(m, p);
3419
-					free(p);
3420
-					p = cli_strtok(ptr, 1, ";");
3421
-					messageAddArgument(m, p);
3425
+					messageAddArgument(m, cli_strtokbuf(ptr, 1, ";", buf));
3422 3426
 				}
3423
-				free(p);
3424 3427
 			}
3425 3428
 			if((p = (char *)messageFindArgument(m, "filename")) == NULL)
3426 3429
 				/*
... ...
@@ -3436,6 +3444,8 @@ parseMimeHeader(message *m, const char *cmd, const table_t *rfc821Table, const c
3436 3436
 	}
3437 3437
 	if(copy)
3438 3438
 		free(copy);
3439
+	if(buf)
3440
+		free(buf);
3439 3441
 
3440 3442
 	return 0;
3441 3443
 }
... ...
@@ -5030,7 +5040,8 @@ do_multipart(message *mainMessage, message **messages, int i, mbox_status *rc, m
5030 5030
 	if(*rc != VIRUS) {
5031 5031
 		if(addToText) {
5032 5032
 			cli_dbgmsg("Adding to non mime-part\n");
5033
-			*tptr = textAdd(*tptr, messageGetBody(aMessage));
5033
+			if(messageGetBody(aMessage))
5034
+				*tptr = textMove(*tptr, messageGetBody(aMessage));
5034 5035
 		} else {
5035 5036
 			fileblob *fb = messageToFileblob(aMessage, mctx->dir, 1);
5036 5037
 
... ...
@@ -1100,8 +1100,6 @@ messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy
1100 1100
 			/*
1101 1101
 			 * FIXME: We've probably run out of memory during the
1102 1102
 			 * text to blob.
1103
-			 * TODO: if m->numberOfEncTypes == 1 we could delete
1104
-			 * the text object as we decode it
1105 1103
 			 */
1106 1104
 			cli_warnmsg("Couldn't start binhex parser\n");
1107 1105
 			(*destroy)(ret);
... ...
@@ -2246,25 +2244,23 @@ decode(message *m, const char *in, unsigned char *out, unsigned char (*decoder)(
2246 2246
 		}
2247 2247
 
2248 2248
 		switch(nbytes) {
2249
+			case 4:
2250
+				*out++ = (b1 << 2) | ((b2 >> 4) & 0x3);
2251
+				*out++ = (b2 << 4) | ((b3 >> 2) & 0xF);
2252
+				*out++ = (b3 << 6) | (b4 & 0x3F);
2253
+				continue;
2249 2254
 			case 3:
2250 2255
 				m->base64_3 = b3;
2251 2256
 			case 2:
2252 2257
 				m->base64_2 = b2;
2253 2258
 			case 1:
2254 2259
 				m->base64_1 = b1;
2255
-				break;
2256
-			case 4:
2257
-				*out++ = (b1 << 2) | ((b2 >> 4) & 0x3);
2258
-				*out++ = (b2 << 4) | ((b3 >> 2) & 0xF);
2259
-				*out++ = (b3 << 6) | (b4 & 0x3F);
2260
+				m->base64chars = nbytes;
2260 2261
 				break;
2261 2262
 			default:
2262 2263
 				assert(0);
2263 2264
 		}
2264
-		if(nbytes != 4) {
2265
-			m->base64chars = nbytes;
2266
-			break;
2267
-		}
2265
+		break;	/* nbytes != 4 => EOL */
2268 2266
 	}
2269 2267
 	return out;
2270 2268
 }
... ...
@@ -116,6 +116,7 @@ static	char	const	rcsid[] = "$Id: text.c,v 1.25 2007/02/12 20:46:09 njh Exp $";
116 116
 #include "mbox.h"
117 117
 
118 118
 static	text	*textCopy(const text *t_head);
119
+static	text	*textAdd(text *t_head, const text *t);
119 120
 static	void	addToFileblob(const line_t *line, void *arg);
120 121
 static	void	getLength(const line_t *line, void *arg);
121 122
 static	void	addToBlob(const line_t *line, void *arg);
... ...
@@ -180,14 +181,19 @@ textCopy(const text *t_head)
180 180
 }
181 181
 
182 182
 /* Add a copy of a text to the end of the current object */
183
-text *
183
+static text *
184 184
 textAdd(text *t_head, const text *t)
185 185
 {
186 186
 	text *ret;
187 187
 	int count;
188 188
 
189
-	if(t_head == NULL)
189
+	if(t_head == NULL) {
190
+		if(t == NULL) {
191
+			cli_errmsg("textAdd fails sanity check\n");
192
+			return NULL;
193
+		}
190 194
 		return textCopy(t);
195
+	}
191 196
 
192 197
 	if(t == NULL)
193 198
 		return t_head;
... ...
@@ -234,16 +240,69 @@ textAddMessage(text *aText, message *aMessage)
234 234
 	else {
235 235
 		text *anotherText = messageToText(aMessage);
236 236
 
237
-		if(aText) {
238
-			aText = textAdd(aText, anotherText);
239
-			textDestroy(anotherText);
240
-			return aText;
241
-		}
237
+		if(aText)
238
+			return textMove(aText, anotherText);
242 239
 		return anotherText;
243 240
 	}
244 241
 }
245 242
 
246 243
 /*
244
+ * Put the contents of the given text at the end of the current object.
245
+ * The given text emptied; it can be used again if needed, though be warned that
246
+ * it will have an empty line at the start.
247
+ */
248
+text *
249
+textMove(text *t_head, text *t)
250
+{
251
+	text *ret;
252
+
253
+	if(t_head == NULL) {
254
+		if(t == NULL) {
255
+			cli_errmsg("textMove fails sanity check\n");
256
+			return NULL;
257
+		}
258
+		t_head = (text *)cli_malloc(sizeof(text));
259
+		if(t_head == NULL)
260
+			return NULL;
261
+		t_head->t_line = t->t_line;
262
+		t_head->t_next = t->t_next;
263
+		t->t_line = NULL;
264
+		t->t_next = NULL;
265
+		return t_head;
266
+	}
267
+
268
+	if(t == NULL)
269
+		return t_head;
270
+
271
+	ret = t_head;
272
+
273
+	while(t_head->t_next)
274
+		t_head = t_head->t_next;
275
+
276
+	/*
277
+	 * Move the first line manually so that the caller is left clean but
278
+	 * empty, the rest is moved by a simple pointer reassignment
279
+	 */
280
+	t_head->t_next = (text *)cli_malloc(sizeof(text));
281
+	if(t_head->t_next == NULL)
282
+		return NULL;
283
+	t_head = t_head->t_next;
284
+
285
+	assert(t_head != NULL);
286
+
287
+	if(t->t_line) {
288
+		t_head->t_line = t->t_line;
289
+		t->t_line = NULL;
290
+	} else
291
+		t_head->t_line = NULL;
292
+
293
+	t_head->t_next = t->t_next;
294
+	t->t_next = NULL;
295
+
296
+	return ret;
297
+}
298
+
299
+/*
247 300
  * Transfer the contents of the text into a blob
248 301
  * The caller must free the returned blob if b is NULL
249 302
  */
... ...
@@ -365,7 +424,8 @@ addToFileblob(const line_t *line, void *arg)
365 365
 	if(line) {
366 366
 		const char *l = lineGetData(line);
367 367
 
368
-		fileblobAddData(fb, (const unsigned char *)l, strlen(l));
368
+		if(l)
369
+			fileblobAddData(fb, (const unsigned char *)l, strlen(l));
369 370
 	}
370 371
 	fileblobAddData(fb, (const unsigned char *)"\n", 1);
371 372
 }
... ...
@@ -373,6 +433,11 @@ addToFileblob(const line_t *line, void *arg)
373 373
 static void *
374 374
 textIterate(text *t_text, void (*cb)(const line_t *item, void *arg), void *arg, int destroy)
375 375
 {
376
+	/*
377
+	 * Have two loops rather than one, so that we're not checking the
378
+	 * value of "destroy" lots and lots of times
379
+	 */
380
+#if	0
376 381
 	while(t_text) {
377 382
 		(*cb)(t_text->t_line, arg);
378 383
 
... ...
@@ -383,5 +448,24 @@ textIterate(text *t_text, void (*cb)(const line_t *item, void *arg), void *arg,
383 383
 
384 384
 		t_text = t_text->t_next;
385 385
 	}
386
+#else
387
+	if(destroy)
388
+		while(t_text) {
389
+			(*cb)(t_text->t_line, arg);
390
+
391
+			if(t_text->t_line) {
392
+				lineUnlink(t_text->t_line);
393
+				t_text->t_line = NULL;
394
+			}
395
+
396
+			t_text = t_text->t_next;
397
+		}
398
+	else
399
+		while(t_text) {
400
+			(*cb)(t_text->t_line, arg);
401
+
402
+			t_text = t_text->t_next;
403
+		}
404
+#endif
386 405
 	return arg;
387 406
 }
... ...
@@ -40,6 +40,7 @@
40 40
  *
41 41
  */
42 42
 
43
+/* The contents could change, ONLY access in text.c */
43 44
 typedef struct text {
44 45
 	line_t	*t_line;	/* NULL if the line is empty */
45 46
 	struct	text	*t_next;
... ...
@@ -49,7 +50,7 @@ typedef struct text {
49 49
 
50 50
 void	textDestroy(text *t_head);
51 51
 text	*textClean(text *t_head);
52
-text	*textAdd(text *t_head, const text *t);
53 52
 text	*textAddMessage(text *aText, message *aMessage);
53
+text	*textMove(text *t_head, text *t);
54 54
 blob	*textToBlob(text *t, blob *b, int destroy);
55 55
 fileblob	*textToFileblob(text *t, fileblob *fb, int destroy);