Use line.[ch]

git-svn: trunk@775
remotes/push_mirror/metadata
Nigel Horne 21 years ago
parent 1a83f3b964
commit b2223aad3a
  1. 6
      clamav-devel/ChangeLog
  2. 62
      clamav-devel/libclamav/line.c
  3. 11
      clamav-devel/libclamav/line.h
  4. 138
      clamav-devel/libclamav/mbox.c
  5. 225
      clamav-devel/libclamav/message.c
  6. 8
      clamav-devel/libclamav/message.h
  7. 41
      clamav-devel/libclamav/text.c
  8. 5
      clamav-devel/libclamav/text.h

@ -1,3 +1,9 @@
Sat Aug 21 12:59:43 BST 2004 (njh)
----------------------------------
* libclamav: Changed the handling of miltipart messages, that is scanning
emails with attachments. Reports on impact on memory
usage and speed welcome to clamav-devel@clamav.net
Fri Aug 20 21:05:04 CEST 2004 (tk)
----------------------------------
* libclamav/Makefile.am: add line.[ch]

@ -16,12 +16,15 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: line.c,v $
* Revision 1.2 2004/08/21 11:57:57 nigelhorne
* Use line.[ch]
*
* Revision 1.1 2004/08/20 11:58:20 nigelhorne
* First draft
*
*/
static char const rcsid[] = "$Id: line.c,v 1.1 2004/08/20 11:58:20 nigelhorne Exp $";
static char const rcsid[] = "$Id: line.c,v 1.2 2004/08/21 11:57:57 nigelhorne Exp $";
#if HAVE_CONFIG_H
#include "clamav-config.h"
@ -33,16 +36,17 @@ static char const rcsid[] = "$Id: line.c,v 1.1 2004/08/20 11:58:20 nigelhorne Ex
#include "line.h"
#include "others.h"
#ifdef OLD
line_t *
lineCreate(const char *data)
{
line_t *ret = cli_malloc(sizeof(struct line));
line_t *ret = (line_t *)li_malloc(sizeof(struct line));
if(ret == NULL)
return NULL;
ret->l_data = strdup(data);
if(ret->l_data == NULL) {
ret->l_str = strdup(data);
if(ret->l_str == NULL) {
free(ret);
return NULL;
}
@ -61,8 +65,53 @@ lineLink(line_t *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_data);
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)
{
line_t *ret = (line_t *)cli_malloc(strlen(data) + 2);
if(ret == NULL)
return NULL;
ret[0] = (char)1;
strcpy(&ret[1], data);
return ret;
}
line_t *
lineLink(line_t *line)
{
if(line[0] == 127) {
cli_warnmsg("lineLink: linkcount too large\n");
return NULL;
}
line[0]++;
return line;
}
line_t *
lineUnlink(line_t *line)
{
/*printf("%d:\n\t'%s'\n", (int)line[0], &line[1]);*/
if(--line[0] == 0) {
free(line);
return NULL;
}
@ -72,5 +121,6 @@ lineUnlink(line_t *line)
const char *
lineGetData(const line_t *line)
{
return line ? line->l_data : NULL;
return line ? &line[1] : NULL;
}
#endif

@ -16,6 +16,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: line.h,v $
* Revision 1.3 2004/08/21 11:57:57 nigelhorne
* Use line.[ch]
*
* Revision 1.2 2004/08/20 19:06:45 kojm
* add line.[ch]
*
@ -27,10 +30,16 @@
#ifndef __LINE_H
#define __LINE_H
#ifdef OLD
/* easier to read, but slower */
typedef struct line {
char *l_data; /* the line's contents */
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);

@ -17,6 +17,9 @@
*
* Change History:
* $Log: mbox.c,v $
* Revision 1.108 2004/08/21 11:57:57 nigelhorne
* Use line.[ch]
*
* Revision 1.107 2004/08/20 04:55:07 nigelhorne
* FOLLOWURL
*
@ -309,7 +312,7 @@
* Compilable under SCO; removed duplicate code with message.c
*
*/
static char const rcsid[] = "$Id: mbox.c,v 1.107 2004/08/20 04:55:07 nigelhorne Exp $";
static char const rcsid[] = "$Id: mbox.c,v 1.108 2004/08/21 11:57:57 nigelhorne Exp $";
#if HAVE_CONFIG_H
#include "clamav-config.h"
@ -347,6 +350,7 @@ static char const rcsid[] = "$Id: mbox.c,v 1.107 2004/08/20 04:55:07 nigelhorne
#include "table.h"
#include "mbox.h"
#include "blob.h"
#include "line.h"
#include "text.h"
#include "message.h"
#include "others.h"
@ -409,9 +413,9 @@ typedef enum { FALSE = 0, TRUE = 1 } bool;
#undef WITH_CURL
#endif
static message *parseEmailHeaders(message *m, const table_t *rfc821Table, bool destroy);
static message *parseEmailHeaders(const message *m, const table_t *rfc821Table);
static int parseEmailHeader(message *m, const char *line, const table_t *rfc821Table);
static int parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, const char *dir, table_t *rfc821Table, table_t *subtypeTable, unsigned int options);
static int parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, const char *dir, const table_t *rfc821Table, const table_t *subtypeTable, unsigned int options);
static int boundaryStart(const char *line, const char *boundary);
static int endOfMessage(const char *line, const char *boundary);
static int initialiseTables(table_t **rfc821Table, table_t **subtypeTable);
@ -615,7 +619,7 @@ cli_mbox(const char *dir, int desc, unsigned int options)
/*
* End of a message in the mail box
*/
body = parseEmailHeaders(m, rfc821, TRUE);
body = parseEmailHeaders(m, rfc821);
if(body == NULL) {
messageReset(m);
continue;
@ -637,7 +641,7 @@ cli_mbox(const char *dir, int desc, unsigned int options)
cli_dbgmsg("Finished processing message\n");
} else
lastLineWasEmpty = (bool)(buffer[0] == '\0');
if(messageAddLine(m, buffer, 1) < 0)
if(messageAddStr(m, buffer) < 0)
break;
} while(fgets(buffer, sizeof(buffer), fd) != NULL);
@ -655,27 +659,25 @@ cli_mbox(const char *dir, int desc, unsigned int options)
* FIXME: files full of new lines and nothing else are
* handled ungracefully...
*/
do
do {
/*
* No need to preprocess such as cli_chomp() since
* that'll be done by parseEmailHeaders()
*
* TODO: this needlessly creates a message object,
* it'd be better if parseEmailHeaders could also
* read in from a file. I do not want to lump the
* parseEmailHeaders code here, that'd be a duplication
* of code I want to avoid
*/
if(messageAddLine(m, buffer, 1) < 0)
(void)cli_chomp(buffer);
if(messageAddStr(m, buffer) < 0)
break;
while(fgets(buffer, sizeof(buffer), fd) != NULL);
} while(fgets(buffer, sizeof(buffer), fd) != NULL);
}
fclose(fd);
retcode = 0;
body = parseEmailHeaders(m, rfc821, TRUE);
body = parseEmailHeaders(m, rfc821);
messageDestroy(m);
if(body) {
/*
@ -711,14 +713,12 @@ cli_mbox(const char *dir, int desc, unsigned int options)
* 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
* BUT: if 'destroy' is set, the caller has given us a hint than 'm' will
* not be used again before it is destroyed, so we can trash it
*/
static message *
parseEmailHeaders(message *m, const table_t *rfc821, bool destroy)
parseEmailHeaders(const message *m, const table_t *rfc821)
{
bool inHeader = TRUE;
text *t;
const text *t;
message *ret;
bool anyHeadersFound = FALSE;
@ -729,26 +729,15 @@ parseEmailHeaders(message *m, const table_t *rfc821, bool destroy)
ret = messageCreate();
for(t = (text *)messageGetBody(m); t; t = t->t_next) {
char *buffer;
for(t = messageGetBody(m); t; t = t->t_next) {
const char *buffer;
#ifdef CL_THREAD_SAFE
char *strptr;
#endif
if(t->t_text) {
if(destroy) {
buffer = t->t_text;
t->t_text = NULL;
} else {
buffer = strdup(t->t_text);
if(buffer == NULL)
break;
}
if(cli_chomp(buffer) == 0) {
free(buffer);
buffer = NULL;
}
} else
if(t->t_line)
buffer = lineGetData(t->t_line);
else
buffer = NULL;
/*
@ -760,13 +749,12 @@ parseEmailHeaders(message *m, const table_t *rfc821, bool destroy)
/*
* Add all the arguments on the line
*/
if(buffer) {
const char *ptr;
char *copy = strdup(buffer);
for(ptr = strtok_r(buffer, ";", &strptr); ptr; ptr = strtok_r(NULL, ":", &strptr))
for(ptr = strtok_r(copy, ";", &strptr); ptr; ptr = strtok_r(NULL, ":", &strptr))
messageAddArgument(ret, ptr);
free(buffer);
}
free(copy);
} else if(inHeader) {
/*
* A blank line signifies the end of the header and
@ -779,11 +767,10 @@ parseEmailHeaders(message *m, const table_t *rfc821, bool destroy)
if((parseEmailHeader(ret, buffer, rfc821) >= 0) ||
(strncasecmp(buffer, "From ", 5) == 0))
anyHeadersFound = TRUE;
free(buffer);
}
} else {
/*cli_dbgmsg("Add line to body '%s'\n", buffer);*/
if(messageAddLine(ret, buffer, 0) < 0)
if(messageAddLine(ret, t->t_line) < 0)
break;
}
}
@ -861,7 +848,7 @@ parseEmailHeader(message *m, const char *line, const table_t *rfc821)
* 2 for success, attachments not saved
*/
static int /* success or fail */
parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, const char *dir, table_t *rfc821Table, table_t *subtypeTable, unsigned int options)
parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, const char *dir, const table_t *rfc821Table, const table_t *subtypeTable, unsigned int options)
{
message **messages; /* parts of a multipart message */
int inhead, inMimeHead, i, rc = 1, htmltextPart, multiparts = 0;
@ -965,7 +952,7 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con
}
do
if(boundaryStart(t_line->t_text, boundary))
if(boundaryStart(lineGetData(t_line->t_line), boundary))
break;
while((t_line = t_line->t_next) != NULL);
@ -1017,8 +1004,9 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con
* but some viruses insert them
*/
while((t_line = t_line->t_next) != NULL)
if(t_line->t_text &&
(cli_chomp(t_line->t_text) > 0))
if(t_line->t_line &&
/*(cli_chomp(t_line->t_text) > 0))*/
(strlen(lineGetData(t_line->t_line)) > 0))
break;
if(t_line == NULL) {
@ -1038,7 +1026,7 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con
}
do {
const char *line = t_line->t_text;
const char *line = lineGetData(t_line->t_line);
/*cli_dbgmsg("inMimeHead %d inhead %d boundary %s line '%s' next '%s'\n",
inMimeHead, inhead, boundary, line, t_line->t_next ? t_line->t_next->t_text : "(null)");*/
@ -1115,11 +1103,16 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con
* put white space after the ;
*/
inMimeHead = continuationMarker(line);
if(!inMimeHead)
if(t_line->t_next &&
t_line->t_next->t_text &&
((t_line->t_next->t_text[0] == '\t') || (t_line->t_next->t_text[0] == ' ')))
if(!inMimeHead) {
const text *next = t_line->t_next;
if(next && next->t_line) {
const char *data = lineGetData(next->t_line);
if((data[0] == '\t') || (data[0] == ' '))
inMimeHead = TRUE;
}
}
parseEmailHeader(aMessage, line, rfc821Table);
} else if(boundaryStart(line, boundary)) {
@ -1137,7 +1130,7 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con
/* t_line = NULL;*/
break;
} else {
if(messageAddLine(aMessage, line, 1) < 0)
if(messageAddLine(aMessage, t_line->t_line) < 0)
break;
lines++;
}
@ -1342,7 +1335,7 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con
/*
* No plain text version
*/
messageAddLine(aMessage, "No plain text alternative", 1);
messageAddStr(aMessage, "No plain text alternative");
assert(messageGetBody(aMessage) != NULL);
break;
case TEXT:
@ -1404,7 +1397,7 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con
messages[i] = NULL;
continue;
}
messageAddLineAtTop(aMessage,
messageAddStrAtTop(aMessage,
"Received: by clamd");
#ifdef SAVE_TO_DISC
/*
@ -1447,27 +1440,6 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con
* be an attachment
*/
cli_dbgmsg("Found multipart inside multipart\n");
#if 0
if(aMessage) {
body = parseEmailHeaders(aMessage, rfc821Table, TRUE);
if(body) {
assert(aMessage == messages[i]);
messageDestroy(messages[i]);
messages[i] = NULL;
if(mainMessage && (mainMessage != messageIn))
messageDestroy(mainMessage);
/*t = messageToText(body);
rc = parseEmailBody(body, blobs, nBlobs, t, dir, rfc821Table, subtypeTable, options);*/
rc = parseEmailBody(body, blobs, nBlobs, aText, dir, rfc821Table, subtypeTable, options);
/*textDestroy(t);*/
cli_dbgmsg("Finished recursion\n");
mainMessage = body;
}
#else
if(aMessage) {
/*
* The headers were parsed when reading in the
@ -1478,7 +1450,6 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con
assert(aMessage == messages[i]);
messageDestroy(messages[i]);
messages[i] = NULL;
#endif
} else {
rc = parseEmailBody(NULL, blobs, nBlobs, NULL, dir, rfc821Table, subtypeTable, options);
if(mainMessage && (mainMessage != messageIn))
@ -1663,7 +1634,7 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con
}
if((strcasecmp(mimeSubtype, "rfc822") == 0) ||
(strcasecmp(mimeSubtype, "delivery-status") == 0)) {
message *m = parseEmailHeaders(mainMessage, rfc821Table, FALSE);
message *m = parseEmailHeaders(mainMessage, rfc821Table);
if(m) {
cli_dbgmsg("Decode rfc822");
@ -1810,12 +1781,15 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con
* must remain otherwise non bounce messages
* won't be scanned
*/
for(t = t_line; t; t = t->t_next)
if(t->t_text &&
(strncasecmp(t->t_text, encoding, sizeof(encoding) - 1) == 0) &&
(strstr(t->t_text, "7bit") == NULL) &&
(strstr(t->t_text, "8bit") == NULL))
for(t = t_line; t; t = t->t_next) {
const char *txt = lineGetData(t->t_line);
if(txt &&
(strncasecmp(txt, encoding, sizeof(encoding) - 1) == 0) &&
(strstr(txt, "7bit") == NULL) &&
(strstr(txt, "8bit") == NULL))
break;
}
if(t && ((b = textToBlob(t_line, NULL)) != NULL)) {
cli_dbgmsg("Found a bounce message\n");
@ -2399,14 +2373,14 @@ checkURLs(message *m, const char *dir)
continue;
if(*p2 == '\0')
continue;
if(n == MAX_URLS) {
cli_warnmsg("Not all URLs will be scanned\n");
break;
}
if(tableFind(t, p2) == 1) {
cli_dbgmsg("URL %s already downloaded\n", p2);
continue;
}
if(n == MAX_URLS) {
cli_warnmsg("Not all URLs will be scanned\n");
break;
}
(void)tableInsert(t, p2, 1);
cli_dbgmsg("Downloading URL %s to be scanned\n", p2);
strncpy(name, p2, sizeof(name));

@ -17,6 +17,9 @@
*
* Change History:
* $Log: message.c,v $
* Revision 1.72 2004/08/21 11:57:57 nigelhorne
* Use line.[ch]
*
* Revision 1.71 2004/08/13 09:28:16 nigelhorne
* Remove incorrect comment style
*
@ -210,7 +213,7 @@
* uuencodebegin() no longer static
*
*/
static char const rcsid[] = "$Id: message.c,v 1.71 2004/08/13 09:28:16 nigelhorne Exp $";
static char const rcsid[] = "$Id: message.c,v 1.72 2004/08/21 11:57:57 nigelhorne Exp $";
#if HAVE_CONFIG_H
#include "clamav-config.h"
@ -240,6 +243,7 @@ static char const rcsid[] = "$Id: message.c,v 1.71 2004/08/13 09:28:16 nigelhorn
#include <pthread.h>
#endif
#include "line.h"
#include "mbox.h"
#include "table.h"
#include "blob.h"
@ -259,6 +263,7 @@ static char const rcsid[] = "$Id: message.c,v 1.71 2004/08/13 09:28:16 nigelhorn
typedef enum { FALSE = 0, TRUE = 1 } bool;
static void messageIsEncoding(message *m);
static unsigned char *decodeLine(message *m, const char *line, unsigned char *buf, size_t buflen);
static unsigned char *decode(message *m, const char *in, unsigned char *out, unsigned char (*decoder)(char), bool isFast);
static void squeeze(char *s);
@ -814,16 +819,41 @@ messageGetEncoding(const message *m)
return(m->encodingType);
}
int
messageAddLine(message *m, line_t *line)
{
assert(m != NULL);
if(m->body_first == NULL)
m->body_last = m->body_first = (text *)cli_malloc(sizeof(text));
else {
m->body_last->t_next = (text *)cli_malloc(sizeof(text));
m->body_last = m->body_last->t_next;
}
if(m->body_last == NULL)
return -1;
m->body_last->t_next = NULL;
if(line && lineGetData(line)) {
m->body_last->t_line = lineLink(line);
messageIsEncoding(m);
} else
m->body_last->t_line = NULL;
return 1;
}
/*
* Add the given line to the end of the given message
* If needed a copy of the given line is taken which the caller must free
* Line must not be terminated by a \n
*/
int
messageAddLine(message *m, const char *line, int takeCopy)
messageAddStr(message *m, const char *data)
{
static const char encoding[] = "Content-Transfer-Encoding";
static const char binhex[] = "(This file must be converted with BinHex 4.0)";
assert(m != NULL);
if(m->body_first == NULL)
@ -838,40 +868,18 @@ messageAddLine(message *m, const char *line, int takeCopy)
m->body_last->t_next = NULL;
if(line && *line) {
if(takeCopy) {
m->body_last->t_text = strdup(line);
if(m->body_last->t_text == NULL) {
cli_errmsg("messageAddLine: out of memory\n");
if(data && *data) {
m->body_last->t_line = lineCreate(data);
if(m->body_last->t_line == NULL) {
cli_errmsg("messageAddStr: out of memory\n");
return -1;
}
/* cli_chomp(m->body_last->t_text); */
} else
m->body_last->t_text = (char *)line;
/*
* See if this line marks the start of a non MIME inclusion that
* will need to be scanned
*/
if((m->encoding == NULL) &&
(strncasecmp(line, encoding, sizeof(encoding) - 1) == 0) &&
(strstr(line, "7bit") == NULL))
m->encoding = m->body_last;
else if(/*(m->bounce == NULL) &&*/
(cli_filetype(line, strlen(line)) == CL_MAILFILE))
m->bounce = m->body_last;
else if((m->binhex == NULL) &&
(strncasecmp(line, binhex, sizeof(binhex) - 1) == 0))
m->binhex = m->body_last;
else if((m->uuencode == NULL) &&
((strncasecmp(line, "begin ", 6) == 0) &&
(isdigit(line[6])) &&
(isdigit(line[7])) &&
(isdigit(line[8])) &&
(line[9] == ' ')))
m->uuencode = m->body_last;
messageIsEncoding(m);
} else
m->body_last->t_text = NULL;
m->body_last->t_line = NULL;
return 1;
}
@ -882,14 +890,14 @@ messageAddLine(message *m, const char *line, int takeCopy)
* Line must not be terminated by a \n
*/
int
messageAddLineAtTop(message *m, const char *line)
messageAddStrAtTop(message *m, const char *data)
{
text *oldfirst;
assert(m != NULL);
if(m->body_first == NULL)
return messageAddLine(m, line, 1);
return messageAddLine(m, lineCreate(data));
oldfirst = m->body_first;
m->body_first = (text *)cli_malloc(sizeof(text));
@ -899,15 +907,45 @@ messageAddLineAtTop(message *m, const char *line)
}
m->body_first->t_next = oldfirst;
m->body_first->t_text = strdup((line) ? line : "");
m->body_first->t_line = lineCreate((data) ? data : "");
if(m->body_first->t_text == NULL) {
cli_errmsg("messageAddLineAtTop: out of memory\n");
if(m->body_first->t_line == NULL) {
cli_errmsg("messageAddStrAtTop: out of memory\n");
return -1;
}
return 1;
}
/*
* See if the last line marks the start of a non MIME inclusion that
* will need to be scanned
*/
static void
messageIsEncoding(message *m)
{
static const char encoding[] = "Content-Transfer-Encoding";
static const char binhex[] = "(This file must be converted with BinHex 4.0)";
const char *line = lineGetData(m->body_last->t_line);
if((m->encoding == NULL) &&
(strncasecmp(line, encoding, sizeof(encoding) - 1) == 0) &&
(strstr(line, "7bit") == NULL))
m->encoding = m->body_last;
else if(/*(m->bounce == NULL) &&*/
(cli_filetype(line, strlen(line)) == CL_MAILFILE))
m->bounce = m->body_last;
else if((m->binhex == NULL) &&
(strncasecmp(line, binhex, sizeof(binhex) - 1) == 0))
m->binhex = m->body_last;
else if((m->uuencode == NULL) &&
((strncasecmp(line, "begin ", 6) == 0) &&
(isdigit(line[6])) &&
(isdigit(line[7])) &&
(isdigit(line[8])) &&
(line[9] == ' ')))
m->uuencode = m->body_last;
}
/*
* Returns a pointer to the body of the message. Note that it does NOT return
* a copy of the data
@ -961,7 +999,7 @@ messageToBlob(message *m)
return NULL;
}
filename = cli_strtok(t_line->t_text, 2, " ");
filename = cli_strtok(lineGetData(t_line->t_line), 2, " ");
if(filename == NULL) {
cli_dbgmsg("UUencoded attachment sent with no filename\n");
@ -1013,8 +1051,10 @@ messageToBlob(message *m)
* See RFC1741
*/
while((t_line = t_line->t_next) != NULL)
if(t_line->t_text)
blobAddData(tmp, (unsigned char *)t_line->t_text, strlen(t_line->t_text));
if(t_line->t_line) {
const char *d = lineGetData(t_line->t_line);
blobAddData(tmp, (unsigned char *)d, strlen(d));
}
data = blobGetData(tmp);
@ -1239,9 +1279,6 @@ messageToBlob(message *m)
return b;
} else {
/*
* Discard attachments with no filename
*/
filename = (char *)messageFindArgument(m, "filename");
if(filename == NULL) {
filename = (char *)messageFindArgument(m, "name");
@ -1282,7 +1319,7 @@ messageToBlob(message *m)
do {
unsigned char data[1024];
unsigned char *uptr;
const char *line = t_line->t_text;
const char *line = lineGetData(t_line->t_line);
if(messageGetEncoding(m) == UUENCODE) {
/*
@ -1353,14 +1390,12 @@ messageToText(message *m)
last = last->t_next;
}
if((last == NULL) ||
((last->t_text = strdup(t_line->t_text)) == NULL)) {
if(last)
free(last);
if(last == NULL) {
if(first)
textDestroy(first);
return NULL;
}
last->t_line = lineLink(t_line->t_line);
}
else {
if(messageGetEncoding(m) == UUENCODE) {
@ -1380,7 +1415,7 @@ messageToText(message *m)
for(; t_line; t_line = t_line->t_next) {
unsigned char data[1024];
unsigned char *uptr;
const char *line = t_line->t_text;
const char *line = lineGetData(t_line->t_line);
if(messageGetEncoding(m) == BASE64) {
/*
@ -1410,7 +1445,7 @@ messageToText(message *m)
if(last == NULL)
break;
last->t_text = data[0] ? strdup((char *)data) : NULL;
last->t_line = ((data[0] != '\n') && data[0]) ? lineCreate((char *)data) : NULL;
if(line && messageGetEncoding(m) == BASE64)
if(strchr(line, '='))
@ -1418,11 +1453,9 @@ messageToText(message *m)
}
if(m->base64chars) {
unsigned char data[4];
unsigned char *ptr;
memset(data, '\0', sizeof(data));
ptr = decode(m, NULL, data, base64, FALSE);
if(ptr) {
if(decode(m, NULL, data, base64, FALSE)) {
if(first == NULL)
first = last = cli_malloc(sizeof(text));
else {
@ -1431,7 +1464,7 @@ messageToText(message *m)
}
if(last != NULL)
last->t_text = data[0] ? strdup((char *)data) : NULL;
last->t_line = data[0] ? lineCreate((char *)data) : NULL;
}
m->base64chars = 0;
}
@ -1642,10 +1675,11 @@ decodeLine(message *m, const char *line, unsigned char *buf, size_t buflen)
if(copy == NULL)
break;
squeeze(copy);
p2 = strchr(copy, '=');
if(p2)
*p2 = '\0';
squeeze(copy);
/*
* Klez doesn't always put "=" on the last line
@ -1714,7 +1748,6 @@ squeeze(char *s)
* decoded. After the last line is found, decode will be called with in = NULL
* to flush these out
*/
#if 1
static unsigned char *
decode(message *m, const char *in, unsigned char *out, unsigned char (*decoder)(char), bool isFast)
{
@ -1866,84 +1899,6 @@ decode(message *m, const char *in, unsigned char *out, unsigned char (*decoder)(
}
return out;
}
#else
static unsigned char *
decode(message *m, const char *in, unsigned char *out, unsigned char (*decoder)(char), bool isFast)
{
unsigned char b1, b2, b3, b4;
/*cli_dbgmsg("decode %s (len %d ifFast %d)\n", in, strlen(in), isFast);*/
if(isFast)
/* Fast decoding if not last line */
while(*in) {
b1 = (*decoder)(*in++);
b2 = (*decoder)(*in++);
b3 = (*decoder)(*in++);
/*
* Put this line here to help on some compilers which
* can make use of some architecure's ability to
* multiprocess when different variables can be
* updated at the same time - here b3 is used in
* one line, b1/b2 in the next and b4 in the next after
* that, b3 and b4 rely on in but b1/b2 don't
*/
*out++ = (b1 << 2) | ((b2 >> 4) & 0x3);
b4 = (*decoder)(*in++);
*out++ = (b2 << 4) | ((b3 >> 2) & 0xF);
*out++ = (b3 << 6) | (b4 & 0x3F);
}
else
/* Slower decoding for last line */
while(*in) {
int nbytes;
b1 = (*decoder)(*in++);
if(*in == '\0') {
b2 = '\0';
nbytes = 1;
} else {
b2 = (*decoder)(*in++);
if(*in == '\0') {
b3 = '\0';
nbytes = 2;
} else {
b3 = (*decoder)(*in++);
if(*in == '\0') {
b4 = '\0';
nbytes = 3;
} else {
b4 = (*decoder)(*in++);
nbytes = 4;
}
}
}
switch(nbytes) {
case 3:
b4 = '\0';
/* fall through */
case 4:
*out++ = (b1 << 2) | ((b2 >> 4) & 0x3);
*out++ = (b2 << 4) | ((b3 >> 2) & 0xF);
*out++ = (b3 << 6) | (b4 & 0x3F);
break;
case 2:
*out++ = (b1 << 2) | ((b2 >> 4) & 0x3);
*out++ = b2 << 4;
break;
case 1:
*out++ = b1 << 2;
break;
default:
assert(0);
}
if(nbytes != 4)
break;
}
return out;
}
#endif
static unsigned char
hex(char c)

@ -16,6 +16,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: message.h,v $
* Revision 1.13 2004/08/21 11:57:57 nigelhorne
* Use line.[ch]
*
* Revision 1.12 2004/07/20 14:35:29 nigelhorne
* Some MYDOOM.I were getting through
*
@ -83,8 +86,9 @@ void messageAddArguments(message *m, const char *arg);
const char *messageFindArgument(const message *m, const char *variable);
void messageSetEncoding(message *m, const char *enctype);
encoding_type messageGetEncoding(const message *m);
int messageAddLine(message *m, const char *line, int takeCopy);
int messageAddLineAtTop(message *m, const char *line);
int messageAddLine(message *m, line_t *line);
int messageAddStr(message *m, const char *data);
int messageAddStrAtTop(message *m, const char *data);
const text *messageGetBody(const message *m);
void messageClean(message *m);
blob *messageToBlob(message *m);

@ -16,6 +16,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: text.c,v $
* Revision 1.9 2004/08/21 11:57:57 nigelhorne
* Use line.[ch]
*
* Revision 1.8 2004/07/20 14:35:29 nigelhorne
* Some MYDOOM.I were getting through
*
@ -33,7 +36,7 @@
*
*/
static char const rcsid[] = "$Id: text.c,v 1.8 2004/07/20 14:35:29 nigelhorne Exp $";
static char const rcsid[] = "$Id: text.c,v 1.9 2004/08/21 11:57:57 nigelhorne Exp $";
#if HAVE_CONFIG_H
#include "clamav-config.h"
@ -45,13 +48,16 @@ static char const rcsid[] = "$Id: text.c,v 1.8 2004/07/20 14:35:29 nigelhorne Ex
#include <sys/malloc.h>
#else
#ifdef HAVE_MALLOC_H /* tk: FreeBSD-CURRENT doesn't support malloc.h */
#ifndef C_BSD /* BSD now uses stdlib.h */
#include <malloc.h>
#endif
#endif
#endif
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include "line.h"
#include "mbox.h"
#include "blob.h"
#include "text.h"
@ -62,8 +68,8 @@ textDestroy(text *t_head)
{
while(t_head) {
text *t_next = t_head->t_next;
if(t_head->t_text)
free(t_head->t_text);
if(t_head->t_line)
lineUnlink(t_head->t_line);
free(t_head);
t_head = t_next;
}
@ -154,11 +160,10 @@ textCopy(const text *t_head)
assert(last != NULL);
if(t_head->t_text) {
last->t_text = strdup(t_head->t_text);
assert(last->t_text != NULL);
} else
last->t_text = NULL;
if(t_head->t_line)
last->t_line = lineLink(t_head->t_line);
else
last->t_line = NULL;
t_head = t_head->t_next;
}
@ -192,11 +197,10 @@ textAdd(text *t_head, const text *t)
assert(t_head != NULL);
if(t->t_text) {
t_head->t_text = strdup(t->t_text);
assert(t_head->t_text != NULL);
} else
t_head->t_text = NULL;
if(t->t_line)
t_head->t_line = lineLink(t->t_line);
else
t_head->t_line = NULL;
t = t->t_next;
}
@ -248,16 +252,19 @@ textToBlob(const text *t, blob *b)
}
for(t1 = t; t1; t1 = t1->t_next)
if(t1->t_text)
s += strlen(t1->t_text) + 1;
if(t1->t_line)
s += strlen(lineGetData(t1->t_line)) + 1;
else
s++;
blobGrow(b, s);
do {
if(t->t_text)
blobAddData(b, (unsigned char *)t->t_text, strlen(t->t_text));
if(t->t_line) {
const char *l = lineGetData(t->t_line);
blobAddData(b, (unsigned char *)l, strlen(l));
}
blobAddData(b, (unsigned char *)"\n", 1);
} while((t = t->t_next) != NULL);

@ -16,6 +16,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: text.h,v $
* Revision 1.5 2004/08/21 11:57:57 nigelhorne
* Use line.[ch]
*
* Revision 1.4 2004/07/20 14:35:29 nigelhorne
* Some MYDOOM.I were getting through
*
@ -25,7 +28,7 @@
*/
typedef struct text {
char *t_text; /* NULL if the line is empty */
line_t *t_line; /* NULL if the line is empty */
struct text *t_next;
} text;

Loading…
Cancel
Save