git-svn: trunk@2600
Nigel Horne authored on 2007/01/08 06:31:43... | ... |
@@ -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.369 2006/12/30 17:10:08 njh Exp $"; |
|
19 |
+static char const rcsid[] = "$Id: mbox.c,v 1.370 2007/01/07 21:30:49 njh Exp $"; |
|
20 | 20 |
|
21 | 21 |
#ifdef _MSC_VER |
22 | 22 |
#include <winsock.h> /* only needed in CL_EXPERIMENTAL */ |
... | ... |
@@ -100,7 +100,7 @@ static void print_trace(int use_syslog); |
100 | 100 |
#define strtok_r(a,b,c) strtok(a,b) |
101 | 101 |
#endif |
102 | 102 |
|
103 |
-#ifdef C_LINUX /* Others??? Old linux, e.g. Red Hat 5.2, doesn't have this */ |
|
103 |
+#ifdef HAVE_STDBOOL_H |
|
104 | 104 |
#include <stdbool.h> |
105 | 105 |
#else |
106 | 106 |
#ifdef FALSE |
... | ... |
@@ -299,6 +299,7 @@ static int exportBounceMessage(text *start, const mbox_ctx *ctx); |
299 | 299 |
static message *do_multipart(message *mainMessage, message **messages, int i, mbox_status *rc, mbox_ctx *mctx, message *messageIn, text **tptr, unsigned int recursion_level); |
300 | 300 |
static int count_quotes(const char *buf); |
301 | 301 |
static bool next_is_folded_header(const text *t); |
302 |
+static bool newline_in_header(const char *line); |
|
302 | 303 |
|
303 | 304 |
static void checkURLs(message *m, mbox_ctx *mctx, mbox_status *rc, int is_html); |
304 | 305 |
|
... | ... |
@@ -1654,7 +1655,7 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch |
1654 | 1654 |
anyHeadersFound = usefulHeader(commandNumber, cmd); |
1655 | 1655 |
continue; |
1656 | 1656 |
} |
1657 |
- fullline = strdup(line); |
|
1657 |
+ fullline = cli_strdup(line); |
|
1658 | 1658 |
fulllinelength = strlen(line) + 1; |
1659 | 1659 |
} else if(line != NULL) { |
1660 | 1660 |
fulllinelength += strlen(line); |
... | ... |
@@ -1735,12 +1736,10 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch |
1735 | 1735 |
* line of the body is in fact |
1736 | 1736 |
* the last lines of the header |
1737 | 1737 |
*/ |
1738 |
- if(strncmp(line, "Message-Id: ", 12) == 0) |
|
1739 |
- continue; |
|
1740 |
- if(strncmp(line, "Date: ", 6) == 0) |
|
1738 |
+ if(newline_in_header(line)) |
|
1741 | 1739 |
continue; |
1740 |
+ bodyIsEmpty = FALSE; |
|
1742 | 1741 |
} |
1743 |
- bodyIsEmpty = FALSE; |
|
1744 | 1742 |
lastBodyLineWasBlank = FALSE; |
1745 | 1743 |
} |
1746 | 1744 |
|
... | ... |
@@ -1810,17 +1809,17 @@ parseEmailHeaders(message *m, const table_t *rfc821) |
1810 | 1810 |
ret = messageCreate(); |
1811 | 1811 |
|
1812 | 1812 |
for(t = messageGetBody(m); t; t = t->t_next) { |
1813 |
- const char *buffer; |
|
1813 |
+ const char *line; |
|
1814 | 1814 |
|
1815 | 1815 |
if(t->t_line) |
1816 |
- buffer = lineGetData(t->t_line); |
|
1816 |
+ line = lineGetData(t->t_line); |
|
1817 | 1817 |
else |
1818 |
- buffer = NULL; |
|
1818 |
+ line = NULL; |
|
1819 | 1819 |
|
1820 | 1820 |
if(inHeader) { |
1821 | 1821 |
cli_dbgmsg("parseEmailHeaders: check '%s'\n", |
1822 |
- buffer ? buffer : ""); |
|
1823 |
- if(buffer == NULL) { |
|
1822 |
+ line ? line : ""); |
|
1823 |
+ if(line == NULL) { |
|
1824 | 1824 |
/* |
1825 | 1825 |
* A blank line signifies the end of |
1826 | 1826 |
* the header and the start of the text |
... | ... |
@@ -1841,15 +1840,15 @@ parseEmailHeaders(message *m, const table_t *rfc821) |
1841 | 1841 |
/* |
1842 | 1842 |
* Continuation of line we're ignoring? |
1843 | 1843 |
*/ |
1844 |
- if(isblank(buffer[0])) |
|
1844 |
+ if(isblank(line[0])) |
|
1845 | 1845 |
continue; |
1846 | 1846 |
|
1847 | 1847 |
/* |
1848 | 1848 |
* Is this a header we're interested in? |
1849 | 1849 |
*/ |
1850 |
- if((strchr(buffer, ':') == NULL) || |
|
1851 |
- (cli_strtokbuf(buffer, 0, ":", cmd) == NULL)) { |
|
1852 |
- if(strncmp(buffer, "From ", 5) == 0) |
|
1850 |
+ if((strchr(line, ':') == NULL) || |
|
1851 |
+ (cli_strtokbuf(line, 0, ":", cmd) == NULL)) { |
|
1852 |
+ if(strncmp(line, "From ", 5) == 0) |
|
1853 | 1853 |
anyHeadersFound = TRUE; |
1854 | 1854 |
continue; |
1855 | 1855 |
} |
... | ... |
@@ -1870,15 +1869,15 @@ parseEmailHeaders(message *m, const table_t *rfc821) |
1870 | 1870 |
anyHeadersFound = usefulHeader(commandNumber, cmd); |
1871 | 1871 |
continue; |
1872 | 1872 |
} |
1873 |
- fullline = strdup(buffer); |
|
1874 |
- fulllinelength = strlen(buffer) + 1; |
|
1875 |
- } else if(buffer) { |
|
1876 |
- fulllinelength += strlen(buffer); |
|
1873 |
+ fullline = cli_strdup(line); |
|
1874 |
+ fulllinelength = strlen(line) + 1; |
|
1875 |
+ } else if(line) { |
|
1876 |
+ fulllinelength += strlen(line); |
|
1877 | 1877 |
ptr = cli_realloc(fullline, fulllinelength); |
1878 | 1878 |
if(ptr == NULL) |
1879 | 1879 |
continue; |
1880 | 1880 |
fullline = ptr; |
1881 |
- strcat(fullline, buffer); |
|
1881 |
+ strcat(fullline, line); |
|
1882 | 1882 |
} |
1883 | 1883 |
|
1884 | 1884 |
assert(fullline != NULL); |
... | ... |
@@ -1904,25 +1903,22 @@ parseEmailHeaders(message *m, const table_t *rfc821) |
1904 | 1904 |
} |
1905 | 1905 |
} else { |
1906 | 1906 |
if(bodyIsEmpty) { |
1907 |
- if(buffer == NULL) |
|
1907 |
+ if(line == NULL) |
|
1908 | 1908 |
/* throw away leading blank lines */ |
1909 | 1909 |
continue; |
1910 |
- cli_dbgmsg("bodyIsEmpty, check \"%s\"\n", buffer); |
|
1911 | 1910 |
/* |
1912 | 1911 |
* Broken message: new line in the |
1913 | 1912 |
* middle of the headers, so the first |
1914 | 1913 |
* line of the body is in fact |
1915 | 1914 |
* the last lines of the header |
1916 | 1915 |
*/ |
1917 |
- if(strncmp(buffer, "Message-Id: ", 12) == 0) |
|
1918 |
- continue; |
|
1919 |
- if(strncmp(buffer, "Date: ", 6) == 0) |
|
1916 |
+ if(newline_in_header(line)) |
|
1920 | 1917 |
continue; |
1921 | 1918 |
bodyIsEmpty = FALSE; |
1922 | 1919 |
} |
1923 | 1920 |
/*if(t->t_line && isuuencodebegin(t->t_line)) |
1924 | 1921 |
puts("FIXME: add fast visa here");*/ |
1925 |
- /*cli_dbgmsg("Add line to body '%s'\n", buffer);*/ |
|
1922 |
+ /*cli_dbgmsg("Add line to body '%s'\n", line);*/ |
|
1926 | 1923 |
if(messageAddLine(ret, t->t_line) < 0) |
1927 | 1924 |
break; |
1928 | 1925 |
} |
... | ... |
@@ -1986,7 +1982,7 @@ parseEmailHeader(message *m, const char *line, const table_t *rfc821) |
1986 | 1986 |
copy = rfc2047(line); |
1987 | 1987 |
if(copy == NULL) |
1988 | 1988 |
/* an RFC checker would return -1 here */ |
1989 |
- copy = strdup(line); |
|
1989 |
+ copy = cli_strdup(line); |
|
1990 | 1990 |
|
1991 | 1991 |
tokenseparater[0] = *separater; |
1992 | 1992 |
tokenseparater[1] = '\0'; |
... | ... |
@@ -2415,7 +2411,7 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx, unsigned int re |
2415 | 2415 |
|
2416 | 2416 |
fullline = rfc822comments(line, NULL); |
2417 | 2417 |
if(fullline == NULL) |
2418 |
- fullline = strdup(line); |
|
2418 |
+ fullline = cli_strdup(line); |
|
2419 | 2419 |
|
2420 | 2420 |
/*quotes = count_quotes(fullline);*/ |
2421 | 2421 |
|
... | ... |
@@ -3566,7 +3562,7 @@ rfc2047(const char *in) |
3566 | 3566 |
size_t len; |
3567 | 3567 |
|
3568 | 3568 |
if((strstr(in, "=?") == NULL) || (strstr(in, "?=") == NULL)) |
3569 |
- return strdup(in); |
|
3569 |
+ return cli_strdup(in); |
|
3570 | 3570 |
|
3571 | 3571 |
cli_dbgmsg("rfc2047 '%s'\n", in); |
3572 | 3572 |
out = cli_malloc(strlen(in) + 1); |
... | ... |
@@ -3610,7 +3606,7 @@ rfc2047(const char *in) |
3610 | 3610 |
if(*++in == '\0') |
3611 | 3611 |
break; |
3612 | 3612 |
|
3613 |
- enctext = strdup(in); |
|
3613 |
+ enctext = cli_strdup(in); |
|
3614 | 3614 |
if(enctext == NULL) { |
3615 | 3615 |
free(out); |
3616 | 3616 |
out = NULL; |
... | ... |
@@ -4010,11 +4006,11 @@ do_checkURLs(message *m, const char *dir, tag_arguments_t *hrefs) |
4010 | 4010 |
|
4011 | 4011 |
#ifdef CL_THREAD_SAFE |
4012 | 4012 |
args[n].dir = dir; |
4013 |
- args[n].url = strdup(url); |
|
4014 |
- args[n].filename = strdup(name); |
|
4013 |
+ args[n].url = cli_strdup(url); |
|
4014 |
+ args[n].filename = cli_strdup(name); |
|
4015 | 4015 |
pthread_create(&tid[n], NULL, getURL, &args[n]); |
4016 | 4016 |
#else |
4017 |
- arg.url = strdup(url); |
|
4017 |
+ arg.url = cli_strdup(url); |
|
4018 | 4018 |
arg.dir = dir; |
4019 | 4019 |
arg.filename = name; |
4020 | 4020 |
getURL(&arg); |
... | ... |
@@ -4156,7 +4152,7 @@ checkURLs(message *m, mbox_ctx *mctx, mbox_status *rc, int is_html) |
4156 | 4156 |
} |
4157 | 4157 |
args[n].dir = mctx->dir; |
4158 | 4158 |
args[n].url = url; |
4159 |
- args[n].filename = strdup(name); |
|
4159 |
+ args[n].filename = cli_strdup(name); |
|
4160 | 4160 |
pthread_create(&tid[n], NULL, getURL, &args[n]); |
4161 | 4161 |
#else |
4162 | 4162 |
/* easy isn't the word I'd use... */ |
... | ... |
@@ -4543,7 +4539,7 @@ getURL(struct arg *arg) |
4543 | 4543 |
while(*end && (*end != '\n')) |
4544 | 4544 |
end++; |
4545 | 4545 |
*end = '\0'; |
4546 |
- arg->url = strdup(location); |
|
4546 |
+ arg->url = cli_strdup(location); |
|
4547 | 4547 |
cli_dbgmsg("Redirecting to %s\n", arg->url); |
4548 | 4548 |
return getURL(arg); |
4549 | 4549 |
} |
... | ... |
@@ -5467,3 +5463,21 @@ next_is_folded_header(const text *t) |
5467 | 5467 |
} |
5468 | 5468 |
return FALSE; |
5469 | 5469 |
} |
5470 |
+ |
|
5471 |
+/* |
|
5472 |
+ * This routine is called on the first line of the body of |
|
5473 |
+ * an email to handle broken messages that have newlines |
|
5474 |
+ * in the middle of its headers |
|
5475 |
+ */ |
|
5476 |
+static bool |
|
5477 |
+newline_in_header(const char *line) |
|
5478 |
+{ |
|
5479 |
+ cli_dbgmsg("newline_in_header, check \"%s\"\n", line); |
|
5480 |
+ |
|
5481 |
+ if(strncmp(line, "Message-Id: ", 12) == 0) |
|
5482 |
+ return TRUE; |
|
5483 |
+ if(strncmp(line, "Date: ", 6) == 0) |
|
5484 |
+ return TRUE; |
|
5485 |
+ |
|
5486 |
+ return FALSE; |
|
5487 |
+} |
... | ... |
@@ -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.192 2006/12/07 09:17:30 njh Exp $"; |
|
19 |
+static char const rcsid[] = "$Id: message.c,v 1.193 2007/01/07 21:30:49 njh Exp $"; |
|
20 | 20 |
|
21 | 21 |
#if HAVE_CONFIG_H |
22 | 22 |
#include "clamav-config.h" |
... | ... |
@@ -60,7 +60,7 @@ static char const rcsid[] = "$Id: message.c,v 1.192 2006/12/07 09:17:30 njh Exp |
60 | 60 |
|
61 | 61 |
#define RFC2045LENGTH 76 /* maximum number of characters on a line */ |
62 | 62 |
|
63 |
-#ifdef C_LINUX /* Others??? Old linux, e.g. Red Hat 5.2, doesn't have this */ |
|
63 |
+#ifdef HAVE_STDBOOL_H |
|
64 | 64 |
#include <stdbool.h> |
65 | 65 |
#else |
66 | 66 |
#ifdef FALSE |
... | ... |
@@ -335,7 +335,7 @@ messageSetMimeSubtype(message *m, const char *subtype) |
335 | 335 |
if(m->mimeSubtype) |
336 | 336 |
free(m->mimeSubtype); |
337 | 337 |
|
338 |
- m->mimeSubtype = strdup(subtype); |
|
338 |
+ m->mimeSubtype = cli_strdup(subtype); |
|
339 | 339 |
} |
340 | 340 |
|
341 | 341 |
const char * |
... | ... |
@@ -365,7 +365,7 @@ messageSetDispositionType(message *m, const char *disptype) |
365 | 365 |
while(*disptype && isspace((int)*disptype)) |
366 | 366 |
disptype++; |
367 | 367 |
if(*disptype) { |
368 |
- m->mimeDispositionType = strdup(disptype); |
|
368 |
+ m->mimeDispositionType = cli_strdup(disptype); |
|
369 | 369 |
if(m->mimeDispositionType) |
370 | 370 |
strstrip(m->mimeDispositionType); |
371 | 371 |
} else |
... | ... |
@@ -516,7 +516,7 @@ messageAddArguments(message *m, const char *s) |
516 | 516 |
* The field is in quotes, so look for the |
517 | 517 |
* closing quotes |
518 | 518 |
*/ |
519 |
- key = strdup(key); |
|
519 |
+ key = cli_strdup(key); |
|
520 | 520 |
|
521 | 521 |
if(key == NULL) |
522 | 522 |
return; |
... | ... |
@@ -539,7 +539,7 @@ messageAddArguments(message *m, const char *s) |
539 | 539 |
continue; |
540 | 540 |
} |
541 | 541 |
|
542 |
- data = strdup(cptr); |
|
542 |
+ data = cli_strdup(cptr); |
|
543 | 543 |
|
544 | 544 |
ptr = (data) ? strchr(data, '"') : NULL; |
545 | 545 |
if(ptr == NULL) { |
... | ... |
@@ -645,7 +645,7 @@ messageFindArgument(const message *m, const char *variable) |
645 | 645 |
} |
646 | 646 |
if((*++ptr == '"') && (strchr(&ptr[1], '"') != NULL)) { |
647 | 647 |
/* Remove any quote characters */ |
648 |
- char *ret = strdup(++ptr); |
|
648 |
+ char *ret = cli_strdup(++ptr); |
|
649 | 649 |
char *p; |
650 | 650 |
|
651 | 651 |
if(ret == NULL) |
... | ... |
@@ -667,7 +667,7 @@ messageFindArgument(const message *m, const char *variable) |
667 | 667 |
} |
668 | 668 |
return ret; |
669 | 669 |
} |
670 |
- return strdup(ptr); |
|
670 |
+ return cli_strdup(ptr); |
|
671 | 671 |
} |
672 | 672 |
} |
673 | 673 |
return NULL; |
... | ... |
@@ -677,8 +677,9 @@ void |
677 | 677 |
messageSetEncoding(message *m, const char *enctype) |
678 | 678 |
{ |
679 | 679 |
const struct encoding_map *e; |
680 |
- int i = 0; |
|
680 |
+ int i; |
|
681 | 681 |
char *type; |
682 |
+ |
|
682 | 683 |
assert(m != NULL); |
683 | 684 |
assert(enctype != NULL); |
684 | 685 |
|
... | ... |
@@ -1391,7 +1392,7 @@ messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy |
1391 | 1391 |
filename = (char *)lineGetData(t_line->t_line); |
1392 | 1392 |
|
1393 | 1393 |
if((filename = strstr(filename, " name=")) != NULL) { |
1394 |
- filename = strdup(&filename[6]); |
|
1394 |
+ filename = cli_strdup(&filename[6]); |
|
1395 | 1395 |
if(filename) { |
1396 | 1396 |
cli_chomp(filename); |
1397 | 1397 |
strstrip(filename); |
... | ... |
@@ -1525,7 +1526,6 @@ messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy |
1525 | 1525 |
lineUnlink(t_line->t_line); |
1526 | 1526 |
t_line->t_line = NULL; |
1527 | 1527 |
} |
1528 |
- |
|
1529 | 1528 |
} while((t_line = t_line->t_next) != NULL); |
1530 | 1529 |
|
1531 | 1530 |
cli_dbgmsg("Exported %u bytes using enctype %d\n", size, enctype); |
... | ... |
@@ -1981,7 +1981,7 @@ decodeLine(message *m, encoding_type et, const char *line, unsigned char *buf, s |
1981 | 1981 |
strcpy(base64buf, line); |
1982 | 1982 |
copy = base64buf; |
1983 | 1983 |
} else { |
1984 |
- copy = strdup(line); |
|
1984 |
+ copy = cli_strdup(line); |
|
1985 | 1985 |
if(copy == NULL) |
1986 | 1986 |
break; |
1987 | 1987 |
} |
... | ... |
@@ -2407,7 +2407,7 @@ rfc2231(const char *in) |
2407 | 2407 |
|
2408 | 2408 |
if(strstr(in, "*0*=") != NULL) { |
2409 | 2409 |
cli_warnmsg("RFC2231 parameter continuations are not yet handled\n"); |
2410 |
- return strdup(in); |
|
2410 |
+ return cli_strdup(in); |
|
2411 | 2411 |
} |
2412 | 2412 |
|
2413 | 2413 |
ptr = strstr(in, "*0="); |
... | ... |
@@ -2423,7 +2423,7 @@ rfc2231(const char *in) |
2423 | 2423 |
} |
2424 | 2424 |
|
2425 | 2425 |
if(ptr == NULL) /* quick return */ |
2426 |
- return strdup(in); |
|
2426 |
+ return cli_strdup(in); |
|
2427 | 2427 |
|
2428 | 2428 |
cli_dbgmsg("rfc2231 '%s'\n", in); |
2429 | 2429 |
|
... | ... |
@@ -2493,7 +2493,7 @@ rfc2231(const char *in) |
2493 | 2493 |
if(field != CONTENTS) { |
2494 | 2494 |
free(ret); |
2495 | 2495 |
cli_warnmsg("Invalid RFC2231 header: '%s'\n", in); |
2496 |
- return strdup(""); |
|
2496 |
+ return cli_strdup(""); |
|
2497 | 2497 |
} |
2498 | 2498 |
|
2499 | 2499 |
*out = '\0'; |
... | ... |
@@ -2534,16 +2534,16 @@ simil(const char *str1, const char *str2) |
2534 | 2534 |
unsigned int score = 0; |
2535 | 2535 |
size_t common, total; |
2536 | 2536 |
size_t len1, len2; |
2537 |
- char ls1[MAX_PATTERN_SIZ], ls2[MAX_PATTERN_SIZ]; |
|
2538 | 2537 |
char *rs1 = NULL, *rs2 = NULL; |
2539 | 2538 |
char *s1, *s2; |
2539 |
+ char ls1[MAX_PATTERN_SIZ], ls2[MAX_PATTERN_SIZ]; |
|
2540 | 2540 |
|
2541 | 2541 |
if(strcasecmp(str1, str2) == 0) |
2542 | 2542 |
return 100; |
2543 | 2543 |
|
2544 |
- if((s1 = strdup(str1)) == NULL) |
|
2544 |
+ if((s1 = cli_strdup(str1)) == NULL) |
|
2545 | 2545 |
return OUT_OF_MEMORY; |
2546 |
- if((s2 = strdup(str2)) == NULL) { |
|
2546 |
+ if((s2 = cli_strdup(str2)) == NULL) { |
|
2547 | 2547 |
free(s1); |
2548 | 2548 |
return OUT_OF_MEMORY; |
2549 | 2549 |
} |
... | ... |
@@ -2596,7 +2596,7 @@ simil(const char *str1, const char *str2) |
2596 | 2596 |
static unsigned int |
2597 | 2597 |
compare(char *ls1, char **rs1, char *ls2, char **rs2) |
2598 | 2598 |
{ |
2599 |
- unsigned int common, diff, maxchars = 0; |
|
2599 |
+ unsigned int common, maxchars = 0; |
|
2600 | 2600 |
bool some_similarity = FALSE; |
2601 | 2601 |
char *s1, *s2; |
2602 | 2602 |
char *maxs1 = NULL, *maxs2 = NULL, *maxe1 = NULL, *maxe2 = NULL; |
... | ... |
@@ -2628,7 +2628,7 @@ compare(char *ls1, char **rs1, char *ls2, char **rs2) |
2628 | 2628 |
while(tolower(*s1) == tolower(*s2)); |
2629 | 2629 |
|
2630 | 2630 |
if(common > maxchars) { |
2631 |
- diff = common - maxchars; |
|
2631 |
+ unsigned int diff = common - maxchars; |
|
2632 | 2632 |
maxchars = common; |
2633 | 2633 |
maxs1 = cs1; |
2634 | 2634 |
maxs2 = cs2; |
... | ... |
@@ -2661,7 +2661,7 @@ push(LINK1 *top, const char *string) |
2661 | 2661 |
|
2662 | 2662 |
if((element = (LINK1)cli_malloc(sizeof(ELEMENT1))) == NULL) |
2663 | 2663 |
return OUT_OF_MEMORY; |
2664 |
- if((element->d1 = strdup(string)) == NULL) |
|
2664 |
+ if((element->d1 = cli_strdup(string)) == NULL) |
|
2665 | 2665 |
return OUT_OF_MEMORY; |
2666 | 2666 |
element->next = *top; |
2667 | 2667 |
*top = element; |