More optimisations

git-svn: trunk@3213
remotes/push_mirror/metadata
Nigel Horne 18 years ago
parent 30e18cafbe
commit 94f051b0ac
  1. 4
      ChangeLog
  2. 54
      libclamav/line.c
  3. 12
      libclamav/line.h
  4. 36
      libclamav/mbox.c
  5. 96
      libclamav/message.c
  6. 2
      libclamav/message.h
  7. 15
      libclamav/text.c
  8. 1
      libclamav/text.h

@ -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) Tue Sep 11 10:33:21 BST 2007 (njh)
---------------------------------- ----------------------------------
* libclamav: Various code clean ups and optimisations * libclamav: Various code clean ups and optimisations

@ -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 "line.h"
#include "others.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 * line_t *
lineCreate(const char *data) lineCreate(const char *data)
{ {
@ -163,10 +116,3 @@ lineGetData(const line_t *line)
{ {
return line ? &line[1] : NULL; return line ? &line[1] : NULL;
} }
unsigned char
lineGetRefCount(const line_t *line)
{
return (unsigned char)line[0];
}
#endif

@ -37,21 +37,13 @@
#ifndef __LINE_H #ifndef __LINE_H
#define __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 */ typedef char line_t; /* first byte is the ref count */
#endif
line_t *lineCreate(const char *data); line_t *lineCreate(const char *data);
line_t *lineLink(line_t *line); line_t *lineLink(line_t *line);
line_t *lineUnlink(line_t *line); line_t *lineUnlink(line_t *line);
const char *lineGetData(const 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 #endif

@ -1705,8 +1705,6 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch
return NULL; return NULL;
} }
messageClean(ret);
cli_dbgmsg("parseEmailFile: return\n"); cli_dbgmsg("parseEmailFile: return\n");
return ret; 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. * The given message contains a raw e-mail.
* *
* Returns the message's body with the correct arguments set * Returns the message's body with the correct arguments set, empties the
* * given message's contents (note that it isn't destroyed)
* 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
* *
* TODO: remove the duplication with parseEmailFile * TODO: remove the duplication with parseEmailFile
*/ */
@ -1729,7 +1723,7 @@ parseEmailHeaders(message *m, const table_t *rfc821)
{ {
bool inHeader = TRUE; bool inHeader = TRUE;
bool bodyIsEmpty = TRUE; bool bodyIsEmpty = TRUE;
const text *t; text *t;
message *ret; message *ret;
bool anyHeadersFound = FALSE; bool anyHeadersFound = FALSE;
int commandNumber = -1; int commandNumber = -1;
@ -1814,13 +1808,15 @@ parseEmailHeaders(message *m, const table_t *rfc821)
fullline = ptr; fullline = ptr;
strcat(fullline, line); strcat(fullline, line);
} }
assert(fullline != NULL); assert(fullline != NULL);
if(next_is_folded_header(t)) if(next_is_folded_header(t))
/* Add arguments to this line */ /* Add arguments to this line */
continue; continue;
lineUnlink(t->t_line);
t->t_line = NULL;
if(count_quotes(fullline) & 1) if(count_quotes(fullline) & 1)
continue; continue;
@ -1853,9 +1849,9 @@ parseEmailHeaders(message *m, const table_t *rfc821)
} }
/*if(t->t_line && isuuencodebegin(t->t_line)) /*if(t->t_line && isuuencodebegin(t->t_line))
puts("FIXME: add fast visa here");*/ puts("FIXME: add fast visa here");*/
/*cli_dbgmsg("Add line to body '%s'\n", line);*/ cli_dbgmsg("parseEmailHeaders: inished with headers, moving body\n");
if(messageAddLine(ret, t->t_line) < 0) messageMoveText(ret, t, m);
break; break;
} }
} }
@ -1878,8 +1874,6 @@ parseEmailHeaders(message *m, const table_t *rfc821)
return NULL; return NULL;
} }
messageClean(ret);
cli_dbgmsg("parseEmailHeaders: return\n"); cli_dbgmsg("parseEmailHeaders: return\n");
return ret; return ret;
@ -2444,8 +2438,6 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx, unsigned int re
if(rc == VIRUS) if(rc == VIRUS)
infected = TRUE; infected = TRUE;
break; break;
default:
messageClean(aMessage);
} }
} }
@ -2543,8 +2535,7 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx, unsigned int re
assert(aMessage == messages[htmltextPart]); assert(aMessage == messages[htmltextPart]);
messageDestroy(aMessage); messageDestroy(aMessage);
messages[htmltextPart] = NULL; messages[htmltextPart] = NULL;
} } else if(rc == VIRUS) {
else if(rc == VIRUS) {
infected = TRUE; infected = TRUE;
break; 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); cli_dbgmsg("Invalid content-type '%s' received, no subtype specified, assuming text/plain; charset=us-ascii\n", ptr);
else { else {
int i; int i;
char *mimeArgs; /* RHS of the ; */
buf = cli_malloc(strlen(ptr) + 1); buf = cli_malloc(strlen(ptr) + 1);
if(buf == NULL) { 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 * we find the boundary argument set it
*/ */
i = 1; i = 1;
while((mimeArgs = cli_strtokbuf(ptr, i++, ";", buf)) != NULL) { while(cli_strtokbuf(ptr, i++, ";", buf) != NULL) {
cli_dbgmsg("mimeArgs = '%s'\n", mimeArgs); cli_dbgmsg("mimeArgs = '%s'\n", buf);
messageAddArguments(m, mimeArgs); messageAddArguments(m, buf);
} }
} }
break; break;

@ -682,7 +682,7 @@ messageGetFilename(const message *m)
if(filename) if(filename)
return filename; return filename;
return (char *)messageFindArgument(m, "name"); return (char *)messageFindArgument(m, "name");
} }
void void
@ -963,6 +963,83 @@ messageAddStrAtTop(message *m, const char *data)
return 1; 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 * See if the last line marks the start of a non MIME inclusion that
* will need to be scanned * 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)"; static const char binhex[] = "(This file must be converted with BinHex 4.0)";
const char *line = lineGetData(m->body_last->t_line); 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) && if((m->encoding == NULL) &&
(strncasecmp(line, encoding, sizeof(encoding) - 1) == 0) && (strncasecmp(line, encoding, sizeof(encoding) - 1) == 0) &&
(strstr(line, "7bit") == NULL)) (strstr(line, "7bit") == NULL))
@ -1014,18 +1086,6 @@ messageGetBody(message *m)
return m->body_first; 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 * Export a message using the given export routines
* *

@ -65,8 +65,8 @@ encoding_type messageGetEncoding(const message *m);
int messageAddLine(message *m, line_t *line); int messageAddLine(message *m, line_t *line);
int messageAddStr(message *m, const char *data); int messageAddStr(message *m, const char *data);
int messageAddStrAtTop(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); text *messageGetBody(message *m);
void messageClean(message *m);
unsigned char *base64Flush(message *m, unsigned char *buf); unsigned char *base64Flush(message *m, unsigned char *buf);
fileblob *messageToFileblob(message *m, const char *dir, int destroy); fileblob *messageToFileblob(message *m, const char *dir, int destroy);
blob *messageToBlob(message *m, int destroy); blob *messageToBlob(message *m, int destroy);

@ -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 */ /* Clone the current object */
static text * static text *
textCopy(const text *t_head) textCopy(const text *t_head)
@ -424,8 +412,7 @@ addToFileblob(const line_t *line, void *arg)
if(line) { if(line) {
const char *l = lineGetData(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); fileblobAddData(fb, (const unsigned char *)"\n", 1);
} }

@ -49,7 +49,6 @@ typedef struct text {
#include "message.h" #include "message.h"
void textDestroy(text *t_head); void textDestroy(text *t_head);
text *textClean(text *t_head);
text *textAddMessage(text *aText, message *aMessage); text *textAddMessage(text *aText, message *aMessage);
text *textMove(text *t_head, text *t); text *textMove(text *t_head, text *t);
blob *textToBlob(text *t, blob *b, int destroy); blob *textToBlob(text *t, blob *b, int destroy);

Loading…
Cancel
Save