diff --git a/ChangeLog b/ChangeLog index d5fe84b2e..64d73866c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Wed Sep 12 13:36:37 BST 2007 (njh) +---------------------------------- + * libclamav: More optimisations + Tue Sep 11 10:33:21 BST 2007 (njh) ---------------------------------- * libclamav: Various code clean ups and optimisations diff --git a/libclamav/line.c b/libclamav/line.c index 30a0c0f71..e4439ab4c 100644 --- a/libclamav/line.c +++ b/libclamav/line.c @@ -69,53 +69,6 @@ static char const rcsid[] = "$Id: line.c,v 1.11 2007/02/12 20:46:08 njh Exp $"; #include "line.h" #include "others.h" -#ifdef OLD -line_t * -lineCreate(const char *data) -{ - line_t *ret = (line_t *)cli_malloc(sizeof(struct line)); - - if(ret == NULL) - return NULL; - - ret->l_str = strdup(data); - if(ret->l_str == NULL) { - free(ret); - return NULL; - } - ret->l_refs = 1; - - return ret; -} - -line_t * -lineLink(line_t *line) -{ - line->l_refs++; - return line; -} - -line_t * -lineUnlink(line_t *line) -{ - /*printf("%d:\n\t'%s'\n", line->l_refs, line->l_str);*/ - - if(--line->l_refs == 0) { - free(line->l_str); - free(line); - return NULL; - } - return line; -} - -const char * -lineGetData(const line_t *line) -{ - return line ? line->l_str : NULL; -} - -#else - line_t * lineCreate(const char *data) { @@ -163,10 +116,3 @@ lineGetData(const line_t *line) { return line ? &line[1] : NULL; } - -unsigned char -lineGetRefCount(const line_t *line) -{ - return (unsigned char)line[0]; -} -#endif diff --git a/libclamav/line.h b/libclamav/line.h index 768e7ef67..4ca02c01b 100644 --- a/libclamav/line.h +++ b/libclamav/line.h @@ -37,21 +37,13 @@ #ifndef __LINE_H #define __LINE_H -#ifdef OLD -/* easier to read, but slower */ - -typedef struct line { - char *l_str; /* the line's contents */ - unsigned int l_refs; /* the number of references to the data */ -} line_t; -#else typedef char line_t; /* first byte is the ref count */ -#endif line_t *lineCreate(const char *data); line_t *lineLink(line_t *line); line_t *lineUnlink(line_t *line); const char *lineGetData(const line_t *line); -unsigned char lineGetRefCount(const line_t *line); + +#define lineGetRefCount(line) ((unsigned char)line[0]) #endif diff --git a/libclamav/mbox.c b/libclamav/mbox.c index a1b665206..267857547 100644 --- a/libclamav/mbox.c +++ b/libclamav/mbox.c @@ -1705,8 +1705,6 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch return NULL; } - messageClean(ret); - cli_dbgmsg("parseEmailFile: return\n"); return ret; @@ -1715,12 +1713,8 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch /* * The given message contains a raw e-mail. * - * Returns the message's body with the correct arguments set - * - * The downside of this approach is that for a short time we have two copies - * of the message in memory, the upside is that it makes for easier parsing - * of encapsulated messages, and in the long run uses less memory in those - * scenarios + * Returns the message's body with the correct arguments set, empties the + * given message's contents (note that it isn't destroyed) * * TODO: remove the duplication with parseEmailFile */ @@ -1729,7 +1723,7 @@ parseEmailHeaders(message *m, const table_t *rfc821) { bool inHeader = TRUE; bool bodyIsEmpty = TRUE; - const text *t; + text *t; message *ret; bool anyHeadersFound = FALSE; int commandNumber = -1; @@ -1814,13 +1808,15 @@ parseEmailHeaders(message *m, const table_t *rfc821) fullline = ptr; strcat(fullline, line); } - assert(fullline != NULL); if(next_is_folded_header(t)) /* Add arguments to this line */ continue; + lineUnlink(t->t_line); + t->t_line = NULL; + if(count_quotes(fullline) & 1) continue; @@ -1853,9 +1849,9 @@ parseEmailHeaders(message *m, const table_t *rfc821) } /*if(t->t_line && isuuencodebegin(t->t_line)) puts("FIXME: add fast visa here");*/ - /*cli_dbgmsg("Add line to body '%s'\n", line);*/ - if(messageAddLine(ret, t->t_line) < 0) - break; + cli_dbgmsg("parseEmailHeaders: inished with headers, moving body\n"); + messageMoveText(ret, t, m); + break; } } @@ -1878,8 +1874,6 @@ parseEmailHeaders(message *m, const table_t *rfc821) return NULL; } - messageClean(ret); - cli_dbgmsg("parseEmailHeaders: return\n"); return ret; @@ -2444,8 +2438,6 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx, unsigned int re if(rc == VIRUS) infected = TRUE; break; - default: - messageClean(aMessage); } } @@ -2543,8 +2535,7 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx, unsigned int re assert(aMessage == messages[htmltextPart]); messageDestroy(aMessage); messages[htmltextPart] = NULL; - } - else if(rc == VIRUS) { + } else if(rc == VIRUS) { infected = TRUE; break; } @@ -3312,7 +3303,6 @@ parseMimeHeader(message *m, const char *cmd, const table_t *rfc821Table, const c cli_dbgmsg("Invalid content-type '%s' received, no subtype specified, assuming text/plain; charset=us-ascii\n", ptr); else { int i; - char *mimeArgs; /* RHS of the ; */ buf = cli_malloc(strlen(ptr) + 1); if(buf == NULL) { @@ -3406,10 +3396,10 @@ parseMimeHeader(message *m, const char *cmd, const table_t *rfc821Table, const c * we find the boundary argument set it */ i = 1; - while((mimeArgs = cli_strtokbuf(ptr, i++, ";", buf)) != NULL) { - cli_dbgmsg("mimeArgs = '%s'\n", mimeArgs); + while(cli_strtokbuf(ptr, i++, ";", buf) != NULL) { + cli_dbgmsg("mimeArgs = '%s'\n", buf); - messageAddArguments(m, mimeArgs); + messageAddArguments(m, buf); } } break; diff --git a/libclamav/message.c b/libclamav/message.c index 172607c6e..b7e2d4422 100644 --- a/libclamav/message.c +++ b/libclamav/message.c @@ -682,7 +682,7 @@ messageGetFilename(const message *m) if(filename) return filename; - return (char *)messageFindArgument(m, "name"); + return (char *)messageFindArgument(m, "name"); } void @@ -963,6 +963,83 @@ messageAddStrAtTop(message *m, const char *data) return 1; } +/* + * Put the contents of the given text at the end of the current object. + * Can be used either to move a text object into a message, or to move a + * message's text into another message only moving from a given offset. + * The given text emptied; it can be used again if needed, though be warned that + * it will have an empty line at the start. + * Returns 0 for failure, 1 for success + */ +int +messageMoveText(message *m, text *t, message *old_message) +{ + int rc; + + if(m->body_first == NULL) { + if(old_message) { + text *u; + /* + * t is within old_message which is about to be + * destroyed + */ + assert(old_message->body_first != NULL); + + m->body_first = t; + for(u = old_message->body_first; u != t;) { + text *next; + + if(u->t_line) + lineUnlink(u->t_line); + next = u->t_next; + + free(u); + u = next; + + if(u == NULL) { + cli_errmsg("messageMoveText sanity check: t not within old_message\n"); + return -1; + } + } + assert(m->body_last->t_next == NULL); + + m->body_last = old_message->body_last; + old_message->body_first = old_message->body_last = NULL; + + /* Do any pointers need to be reset? */ + if((old_message->bounce == NULL) && + (old_message->encoding == NULL) && + (old_message->binhex == NULL) && + (old_message->yenc == NULL)) + return 0; + + m->body_last = m->body_first; + rc = 0; + } else { + m->body_last = m->body_first = textMove(NULL, t); + if(m->body_first == NULL) + rc = -1; + else + rc = 0; + } + } else { + m->body_last = textMove(m->body_last, t); + if(m->body_last == NULL) { + rc = -1; + m->body_last = m->body_first; + } else + rc = 0; + } + + while(m->body_last->t_next) { + m->body_last = m->body_last->t_next; + if(m->body_last->t_line) + messageIsEncoding(m); + } + + return rc; +} + /* * See if the last line marks the start of a non MIME inclusion that * will need to be scanned @@ -974,11 +1051,6 @@ messageIsEncoding(message *m) static const char binhex[] = "(This file must be converted with BinHex 4.0)"; const char *line = lineGetData(m->body_last->t_line); - /* not enough matches to warrant this test */ - /*if(lineGetRefCount(m->body_last->t_line) > 1) { - return; - }*/ - if((m->encoding == NULL) && (strncasecmp(line, encoding, sizeof(encoding) - 1) == 0) && (strstr(line, "7bit") == NULL)) @@ -1014,18 +1086,6 @@ messageGetBody(message *m) return m->body_first; } -/* - * Clean up the message by removing trailing spaces and blank lines - */ -void -messageClean(message *m) -{ - text *newEnd = textClean(m->body_first); - - if(newEnd) - m->body_last = newEnd; -} - /* * Export a message using the given export routines * diff --git a/libclamav/message.h b/libclamav/message.h index 3f1d1a76d..1c91054a5 100644 --- a/libclamav/message.h +++ b/libclamav/message.h @@ -65,8 +65,8 @@ encoding_type messageGetEncoding(const message *m); int messageAddLine(message *m, line_t *line); int messageAddStr(message *m, const char *data); int messageAddStrAtTop(message *m, const char *data); +int messageMoveText(message *m, text *t, message *old_message); text *messageGetBody(message *m); -void messageClean(message *m); unsigned char *base64Flush(message *m, unsigned char *buf); fileblob *messageToFileblob(message *m, const char *dir, int destroy); blob *messageToBlob(message *m, int destroy); diff --git a/libclamav/text.c b/libclamav/text.c index 0a6d54061..bc42b38e1 100644 --- a/libclamav/text.c +++ b/libclamav/text.c @@ -134,18 +134,6 @@ textDestroy(text *t_head) } } -/* - * Remove trailing spaces from the lines and trailing blank lines - * This could be used to remove trailing blank lines, empty lines etc., - * but it probably isn't worth the time taken given that it won't reclaim - * much memory - */ -text * -textClean(text *t_head) -{ - return t_head; -} - /* Clone the current object */ static text * textCopy(const text *t_head) @@ -424,8 +412,7 @@ addToFileblob(const line_t *line, void *arg) if(line) { const char *l = lineGetData(line); - if(l) - fileblobAddData(fb, (const unsigned char *)l, strlen(l)); + fileblobAddData(fb, (const unsigned char *)l, strlen(l)); } fileblobAddData(fb, (const unsigned char *)"\n", 1); } diff --git a/libclamav/text.h b/libclamav/text.h index 501f9553f..a8eeb59d0 100644 --- a/libclamav/text.h +++ b/libclamav/text.h @@ -49,7 +49,6 @@ typedef struct text { #include "message.h" void textDestroy(text *t_head); -text *textClean(text *t_head); text *textAddMessage(text *aText, message *aMessage); text *textMove(text *t_head, text *t); blob *textToBlob(text *t, blob *b, int destroy);