From c74f0c5ea9e707dbf02f00cd00a708c77cfa02a7 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Mon, 6 Nov 2023 11:57:37 -0500 Subject: [PATCH] considering nuclear weapons --- libcitadel/lib/mime_parser.c | 214 +++++++++++++++++------------------ 1 file changed, 104 insertions(+), 110 deletions(-) diff --git a/libcitadel/lib/mime_parser.c b/libcitadel/lib/mime_parser.c index 4017f39cb..65093a2fa 100644 --- a/libcitadel/lib/mime_parser.c +++ b/libcitadel/lib/mime_parser.c @@ -251,8 +251,9 @@ void mime_decode(char *partnum, free(decoded); } -// this is the extract of mime_decode which can be called if 'dont_decode' was set; -// to save the cpu intense process of decoding to the time when it realy wants the content. + +// this is a bastardization of mime_decode() which can be called if 'dont_decode' was set; +// to postpone the cpu intense process of decoding until the time when it realy wants the content. // returns: // - > 0 we decoded something, its on *decoded, you need to free it. // - = 0 no need to decode stuff. *decoded will be NULL. @@ -277,11 +278,9 @@ int mime_decode_now (char *part_start, if (strlen(encoding) == 0) { return 0; } - // Fail if we hit an unknown encoding. - if ((strcasecmp(encoding, "base64")) - && (strcasecmp(encoding, "quoted-printable"))) { + if ((strcasecmp(encoding, "base64")) && (strcasecmp(encoding, "quoted-printable"))) { return -1; } @@ -317,7 +316,7 @@ typedef enum _eIntMimeHdrs { filename, disposition, id, - eMax /* don't move ! */ + eMax // don't move! } eIntMimeHdrs; typedef struct _CBufStr { @@ -332,18 +331,18 @@ typedef struct _interesting_mime_headers { } interesting_mime_headers; -static void FlushInterestingMimes(interesting_mime_headers *m) -{ +static void FlushInterestingMimes(interesting_mime_headers *m) { int i; for (i = 0; i < eMax; i++) { - m->b[i].Key[0] = '\0'; - m->b[i].len = 0; + m->b[i].Key[0] = '\0'; + m->b[i].len = 0; } m->content_length = -1; } -static interesting_mime_headers *InitInterestingMimes(void) -{ + + +static interesting_mime_headers *InitInterestingMimes(void) { interesting_mime_headers *m; m = (interesting_mime_headers*) malloc( sizeof(interesting_mime_headers)); @@ -353,10 +352,7 @@ static interesting_mime_headers *InitInterestingMimes(void) } -static long parse_MimeHeaders(interesting_mime_headers *m, - char** pcontent_start, - char *content_end) -{ +static long parse_MimeHeaders(interesting_mime_headers *m, char** pcontent_start, char *content_end) { char buf[SIZ]; char header[SIZ]; long headerlen; @@ -387,7 +383,7 @@ static long parse_MimeHeaders(interesting_mime_headers *m, m->b[charset].len = extract_key(m->b[charset].Key, CKEY(m->b[content_type]), HKEY("charset"), '='); m->b[boundary].len = extract_key(m->b[boundary].Key, header, headerlen, HKEY("boundary"), '='); - /* Deal with weird headers */ + // Deal with weird headers pch = strchr(m->b[content_type].Key, ' '); if (pch != NULL) { *pch = '\0'; @@ -450,20 +446,21 @@ static long parse_MimeHeaders(interesting_mime_headers *m, static int IsAsciiEncoding(interesting_mime_headers *m) { - if ((m->b[encoding].len != 0) && - (strcasecmp(m->b[encoding].Key, "base64") == 0)) + if ((m->b[encoding].len != 0) && (strcasecmp(m->b[encoding].Key, "base64") == 0)) { return 1; - if ((m->b[encoding].len != 0) && - (strcmp(m->b[encoding].Key, "quoted-printable") == 0)) + } + if ((m->b[encoding].len != 0) && (strcmp(m->b[encoding].Key, "quoted-printable") == 0)) { return 1; + } return 0; } + static char *FindNextContent(char *ptr, - char *content_end, - interesting_mime_headers *SubMimeHeaders, - interesting_mime_headers *m) + char *content_end, + interesting_mime_headers *SubMimeHeaders, + interesting_mime_headers *m) { char *next_boundary; char tmp; @@ -478,7 +475,7 @@ static char *FindNextContent(char *ptr, // to be all accurate, and suspect it to lose one digit // per line with a line length of 80 chars, we need // to start searching a little before.. - + if ((SubMimeHeaders->content_length != -1) && (SubMimeHeaders->content_length > 10)) { char *pptr; long lines; @@ -498,7 +495,7 @@ static char *FindNextContent(char *ptr, // try skipping the content on the search for the next // boundary. since we don't trust the content_length // to be all accurate, start searching a little before.. - + if ((SubMimeHeaders->content_length != -1) && (SubMimeHeaders->content_length > 10)) { char *pptr; pptr = ptr + SubMimeHeaders->content_length - 10; @@ -508,8 +505,8 @@ static char *FindNextContent(char *ptr, srch = next_boundary = NULL; for (srch = memchr(ptr, '-', content_end - ptr); - (srch != NULL) && (srch < content_end); - srch = memchr(srch, '-', content_end - srch)) + (srch != NULL) && (srch < content_end); + srch = memchr(srch, '-', content_end - srch)) { if (!memcmp(srch, m->b[startary].Key, m->b[startary].len)) { next_boundary = srch; @@ -529,14 +526,14 @@ static char *FindNextContent(char *ptr, // Note: NULL can be supplied as content_end; in this case, the message is // considered to have ended when the parser encounters a 0x00 byte. static void recurseable_mime_parser(char *partnum, - char *content_start, char *content_end, - MimeParserCallBackType CallBack, - MimeParserCallBackType PreMultiPartCallBack, - MimeParserCallBackType PostMultiPartCallBack, - void *userdata, - int dont_decode, - interesting_mime_headers *m) -{ + char *content_start, char *content_end, + MimeParserCallBackType CallBack, + MimeParserCallBackType PreMultiPartCallBack, + MimeParserCallBackType PostMultiPartCallBack, + void *userdata, + int dont_decode, + interesting_mime_headers *m +) { interesting_mime_headers *SubMimeHeaders; char *ptr; char *part_start; @@ -548,7 +545,6 @@ static void recurseable_mime_parser(char *partnum, int part_seq = 0; CBufStr *chosen_name; - // If this is a multipart message, then recursively process it ptr = content_start; part_start = NULL; @@ -557,16 +553,17 @@ static void recurseable_mime_parser(char *partnum, // Tell the client about this message's multipartedness if (PreMultiPartCallBack != NULL) { PreMultiPartCallBack("", - "", - partnum, - "", - NULL, - m->b[content_type].Key, - m->b[charset].Key, - 0, - m->b[encoding].Key, - m->b[id].Key, - userdata); + "", + partnum, + "", + NULL, + m->b[content_type].Key, + m->b[charset].Key, + 0, + m->b[encoding].Key, + m->b[id].Key, + userdata + ); } // Figure out where the boundaries are @@ -669,16 +666,17 @@ static void recurseable_mime_parser(char *partnum, if (PostMultiPartCallBack != NULL) { PostMultiPartCallBack("", - "", - partnum, - "", - NULL, - m->b[content_type].Key, - m->b[charset].Key, - 0, - m->b[encoding].Key, - m->b[id].Key, - userdata); + "", + partnum, + "", + NULL, + m->b[content_type].Key, + m->b[charset].Key, + 0, + m->b[encoding].Key, + m->b[id].Key, + userdata + ); } } // If it's not a multipart message, then do something with it @@ -688,19 +686,17 @@ static void recurseable_mime_parser(char *partnum, length = content_end - part_start; ptr = part_end = content_end; - /* The following code will truncate the MIME part to the size - * specified by the Content-length: header. We have commented it - * out because these headers have a tendency to be wrong. - * - * if ( (content_length > 0) && (length > content_length) ) { - * length = content_length; - * } - */ - - /* Sometimes the "name" field is tacked on to Content-type, - * and sometimes it's tacked on to Content-disposition. Use - * whichever one we have. - */ + // The following code will truncate the MIME part to the size + // specified by the Content-length: header. We have commented it + // out because these headers have a tendency to be wrong. + // + // if ( (content_length > 0) && (length > content_length) ) { + // length = content_length; + // } + + // Sometimes the "name" field is tacked on to Content-type, + // and sometimes it's tacked on to Content-disposition. Use + // whichever one we have. if (m->b[content_disposition_name].len > m->b[content_type_name].len) { chosen_name = &m->b[content_disposition_name]; } @@ -710,38 +706,37 @@ static void recurseable_mime_parser(char *partnum, // Ok, we've got a non-multipart part here, so do something with it. mime_decode(partnum, - part_start, - length, - m->b[content_type].Key, - m->b[charset].Key, - m->b[encoding].Key, - m->b[disposition].Key, - m->b[id].Key, - chosen_name->Key, - m->b[filename].Key, - CallBack, - NULL, NULL, - userdata, - dont_decode + part_start, + length, + m->b[content_type].Key, + m->b[charset].Key, + m->b[encoding].Key, + m->b[disposition].Key, + m->b[id].Key, + chosen_name->Key, + m->b[filename].Key, + CallBack, + NULL, + NULL, + userdata, + dont_decode ); - /* - * Now if it's an encapsulated message/rfc822 then we have to recurse into it - */ + // Now if it's an encapsulated message/rfc822 then we have to recurse into it if (!strcasecmp(&m->b[content_type].Key[0], "message/rfc822")) { if (PreMultiPartCallBack != NULL) { PreMultiPartCallBack("", - "", - partnum, - "", - NULL, - m->b[content_type].Key, - m->b[charset].Key, - 0, - m->b[encoding].Key, - m->b[id].Key, - userdata); + "", + partnum, + "", + NULL, + m->b[content_type].Key, + m->b[charset].Key, + 0, + m->b[encoding].Key, + m->b[id].Key, + userdata); } if (CallBack != NULL) { if (strlen(partnum) > 0) { @@ -767,16 +762,17 @@ static void recurseable_mime_parser(char *partnum, } if (PostMultiPartCallBack != NULL) { PostMultiPartCallBack("", - "", - partnum, - "", - NULL, - m->b[content_type].Key, - m->b[charset].Key, - 0, - m->b[encoding].Key, - m->b[id].Key, - userdata); + "", + partnum, + "", + NULL, + m->b[content_type].Key, + m->b[charset].Key, + 0, + m->b[encoding].Key, + m->b[id].Key, + userdata + ); } @@ -892,10 +888,8 @@ const char *GuessMimeType(const char *data, size_t dlen) { } MimeIndex ++; } - /* - * ok, our simple minded algorythm didn't find anything, - * let the big chegger try it, he wil default to application/octet-stream - */ + // ok, our simple minded algorythm didn't find anything, + // let the big chegger try it, he wil default to application/octet-stream return (xdg_mime_get_mime_type_for_data(data, dlen)); } -- 2.30.2