X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=libcitadel%2Flib%2Fmime_parser.c;h=1fc037d43ffd77462434eb93f645001f4dbb251a;hb=8659bf61f03724755374145e6211be6bbfe74fda;hp=3b10588b7a3fc2c0413fc89790bca71f0e762690;hpb=93732f7256027b1f90d92303aab28e479e0a2c00;p=citadel.git diff --git a/libcitadel/lib/mime_parser.c b/libcitadel/lib/mime_parser.c index 3b10588b7..1fc037d43 100644 --- a/libcitadel/lib/mime_parser.c +++ b/libcitadel/lib/mime_parser.c @@ -2,8 +2,20 @@ * This is the MIME parser for Citadel. * * Copyright (c) 1998-2010 by the citadel.org development team. - * This code is distributed under the GNU General Public License v3. * + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include @@ -123,7 +135,7 @@ char *fixed_partnum(char *supplied_partnum) { static inline unsigned int _decode_hex(const char *Source) { - int ret = '?'; + unsigned int ret = '?'; unsigned char LO_NIBBLE; unsigned char HI_NIBBLE; @@ -166,7 +178,6 @@ int CtdlDecodeQuotedPrintable(char *decoded, char *encoded, int sourcelen) { } else { - ch = 0; ch = _decode_hex(&encoded[pos]); pos += 2; decoded[decoded_length++] = ch; @@ -205,11 +216,13 @@ void mime_decode(char *partnum, /* Some encodings aren't really encodings */ if (!strcasecmp(encoding, "7bit")) - strcpy(encoding, ""); + *encoding = '\0'; if (!strcasecmp(encoding, "8bit")) - strcpy(encoding, ""); + *encoding = '\0'; if (!strcasecmp(encoding, "binary")) - strcpy(encoding, ""); + *encoding = '\0'; + if (!strcasecmp(encoding, "ISO-8859-1")) + *encoding = '\0'; /* If this part is not encoded, send as-is */ if ( (strlen(encoding) == 0) || (dont_decode)) { @@ -291,11 +304,11 @@ int mime_decode_now (char *part_start, *decoded = NULL; /* Some encodings aren't really encodings */ if (!strcasecmp(encoding, "7bit")) - strcpy(encoding, ""); + *encoding = '\0'; if (!strcasecmp(encoding, "8bit")) - strcpy(encoding, ""); + *encoding = '\0'; if (!strcasecmp(encoding, "binary")) - strcpy(encoding, ""); + *encoding = '\0'; /* If this part is not encoded, send as-is */ if (strlen(encoding) == 0) { @@ -406,6 +419,7 @@ static long parse_MimeHeaders(interesting_mime_headers *m, if (!isspace(buf[0]) && (headerlen > 0)) { if (!strncasecmp(header, "Content-type:", 13)) { memcpy (m->b[content_type].Key, &header[13], headerlen - 12); + m->b[content_type].Key[headerlen - 12] = '\0'; m->b[content_type].len = striplt (m->b[content_type].Key); m->b[content_type_name].len = extract_key(m->b[content_type_name].Key, CKEY(m->b[content_type]), HKEY("name"), '='); @@ -426,6 +440,7 @@ static long parse_MimeHeaders(interesting_mime_headers *m, } else if (!strncasecmp(header, "Content-Disposition:", 20)) { memcpy (m->b[disposition].Key, &header[20], headerlen - 19); + m->b[disposition].Key[headerlen - 19] = '\0'; m->b[disposition].len = striplt(m->b[disposition].Key); m->b[content_disposition_name].len = extract_key(m->b[content_disposition_name].Key, CKEY(m->b[disposition]), HKEY("name"), '='); @@ -435,7 +450,8 @@ static long parse_MimeHeaders(interesting_mime_headers *m, m->b[disposition].len = striplt(m->b[disposition].Key); } else if (!strncasecmp(header, "Content-ID:", 11)) { - memcpy(m->b[id].Key, &header[11], headerlen); + memcpy(m->b[id].Key, &header[11], headerlen - 11); + m->b[id].Key[headerlen - 11] = '\0'; striplt(m->b[id].Key); m->b[id].len = stripallbut(m->b[id].Key, '<', '>'); } @@ -448,6 +464,7 @@ static long parse_MimeHeaders(interesting_mime_headers *m, } else if (!strncasecmp(header, "Content-transfer-encoding: ", 26)) { memcpy(m->b[encoding].Key, &header[26], headerlen - 26); + m->b[encoding].Key[headerlen - 26] = '\0'; m->b[encoding].len = striplt(m->b[encoding].Key); } *header = '\0'; @@ -536,8 +553,13 @@ static char *FindNextContent(char *ptr, if (pptr < content_end) ptr = pptr; } - next_boundary = NULL; - for (srch=ptr; srchb[startary].Key, m->b[startary].len)) @@ -545,6 +567,8 @@ static char *FindNextContent(char *ptr, next_boundary = srch; srch = content_end; } + else srch ++; + } } @@ -601,21 +625,25 @@ static void recurseable_mime_parser(char *partnum, /* Figure out where the boundaries are */ m->b[startary].len = snprintf(m->b[startary].Key, SIZ, "--%s", m->b[boundary].Key); SubMimeHeaders = InitInterestingMimes (); - if (*ptr == '\r') - ptr ++; - if (*ptr == '\n') - ptr ++; + + while ((*ptr == '\r') || (*ptr == '\n')) ptr ++; + if (strncmp(ptr, m->b[startary].Key, m->b[startary].len) == 0) ptr += m->b[startary].len; - if (*ptr == '\r') - ptr ++; - if (*ptr == '\n') - ptr ++; + + while ((*ptr == '\r') || (*ptr == '\n')) ptr ++; + part_start = NULL; do { + char *optr; + optr = ptr; if (parse_MimeHeaders(SubMimeHeaders, &ptr, content_end) != 0) break; + if ((ptr - optr > 2) && + (*(ptr - 2) == '\r')) + crlf_in_use = 1; + part_start = ptr; next_boundary = FindNextContent(ptr, @@ -623,8 +651,11 @@ static void recurseable_mime_parser(char *partnum, SubMimeHeaders, m); if ((next_boundary != NULL) && - (next_boundary - part_start < 3)) + (next_boundary - part_start < 3)) { + FlushInterestingMimes(SubMimeHeaders); + continue; + } if ( (part_start != NULL) && (next_boundary != NULL) ) { part_end = next_boundary; @@ -658,8 +689,8 @@ static void recurseable_mime_parser(char *partnum, if (next_boundary != NULL) { /* If we pass out of scope, don't attempt to * read past the end boundary. */ - if ((*(next_boundary + m->b[startary].len + 1) == '-') && - (*(next_boundary + m->b[startary].len + 2) == '-') ){ + if ((*(next_boundary + m->b[startary].len) == '-') && + (*(next_boundary + m->b[startary].len + 1) == '-') ){ ptr = content_end; } else { @@ -1026,8 +1057,8 @@ int LoadIconDir(const char *DirName) { char *MinorPtr; char *PStart; -#ifdef _DIRENT_HAVE_D_NAMELEN - d_namelen = filedir_entry->d_namelen; +#ifdef _DIRENT_HAVE_D_NAMLEN + d_namelen = filedir_entry->d_namlen; #else d_namelen = strlen(filedir_entry->d_name); #endif