From 5ec6be769089534e27e2ff235e018c1f7556409b Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Mon, 6 Nov 2023 11:48:36 -0500 Subject: [PATCH] Looks like I need to remove some optimization cancer from mime_parser.c, but first, a bit of style cleanup. --- libcitadel/lib/mime_parser.c | 235 ++++++++++++++--------------------- 1 file changed, 94 insertions(+), 141 deletions(-) diff --git a/libcitadel/lib/mime_parser.c b/libcitadel/lib/mime_parser.c index d6ff049ed..4017f39cb 100644 --- a/libcitadel/lib/mime_parser.c +++ b/libcitadel/lib/mime_parser.c @@ -1,6 +1,6 @@ // This is the MIME parser for Citadel. // -// Copyright (c) 1998-2022 by the citadel.org development team. +// Copyright (c) 1998-2023 by the citadel.org development team. // // This program is open source software. Use, duplication, or disclosure // is subject to the terms of the GNU General Public License, version 3. @@ -21,7 +21,7 @@ #include "libcitadel.h" #include "libcitadellocal.h" -const unsigned char FromHexTable [256] = { +const unsigned char FromHexTable[256] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 10 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 20 @@ -82,12 +82,12 @@ long extract_key(char *target, char *source, long sourcelen, char *key, long key for (ptr=target; (*ptr != 0); ptr++) { - /* A semicolon means we've hit the end of the key, unless we're inside double quotes */ + // A semicolon means we've hit the end of the key, unless we're inside double quotes if ( (double_quotes != 1) && (*ptr == ';')) { *ptr = 0; } - /* if we find double quotes, we've got a great set of string boundaries */ + // if we find double quotes, we've got a great set of string boundaries if (*ptr == '\"') { ++double_quotes; if (double_quotes == 1) { @@ -103,10 +103,8 @@ long extract_key(char *target, char *source, long sourcelen, char *key, long key } -/* - * For non-multipart messages, we need to generate a quickie partnum of "1" - * to return to callback functions. Some callbacks demand it. - */ +// For non-multipart messages, we need to generate a quickie partnum of "1" +// to return to callback functions. Some callbacks demand it. char *fixed_partnum(char *supplied_partnum) { if (supplied_partnum == NULL) return "1"; if (strlen(supplied_partnum)==0) return "1"; @@ -132,10 +130,9 @@ static inline unsigned int _decode_hex(const char *Source) { unsigned int decode_hex(char *Source) {return _decode_hex(Source);} -/* - * Convert "quoted-printable" to binary. Returns number of bytes decoded. - * according to RFC2045 section 6.7 - */ + +// Convert "quoted-printable" to binary. Returns number of bytes decoded. +// according to RFC2045 section 6.7 int CtdlDecodeQuotedPrintable(char *decoded, char *encoded, int sourcelen) { unsigned int ch; int decoded_length = 0; @@ -168,10 +165,8 @@ int CtdlDecodeQuotedPrintable(char *decoded, char *encoded, int sourcelen) { } -/* - * Given a message or message-part body and a length, handle any necessary - * decoding and pass the request up the stack. - */ +// Given a message or message-part body and a length, handle any necessary +// decoding and pass the request up the stack. void mime_decode(char *partnum, char *part_start, size_t length, char *content_type, char *charset, char *encoding, @@ -256,14 +251,12 @@ 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. - * returns: - * - > 0 we decoded something, its on *decoded, you need to free it. - * - = 0 no need to decode stuff. *decoded will be NULL. - * - < 0 an error occured, either an unknown encoding, or alloc failed. no need to free. - */ +// 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. +// returns: +// - > 0 we decoded something, its on *decoded, you need to free it. +// - = 0 no need to decode stuff. *decoded will be NULL. +// - < 0 an error occured, either an unknown encoding, or alloc failed. no need to free. int mime_decode_now (char *part_start, size_t length, char *encoding, @@ -272,7 +265,7 @@ int mime_decode_now (char *part_start, { *bytes_decoded = 0; *decoded = NULL; - /* Some encodings aren't really encodings */ + // Some encodings aren't really encodings if (!strcasecmp(encoding, "7bit")) *encoding = '\0'; if (!strcasecmp(encoding, "8bit")) @@ -280,24 +273,22 @@ int mime_decode_now (char *part_start, if (!strcasecmp(encoding, "binary")) *encoding = '\0'; - /* If this part is not encoded, send as-is */ + // If this part is not encoded, send as-is if (strlen(encoding) == 0) { return 0; } - /* Fail if we hit an unknown encoding. */ + // Fail if we hit an unknown encoding. if ((strcasecmp(encoding, "base64")) && (strcasecmp(encoding, "quoted-printable"))) { return -1; } - /* - * Allocate a buffer for the decoded data. The output buffer is slightly - * larger than the input buffer; this assumes that the decoded data - * will never be significantly larger than the encoded data. This is a - * safe assumption with base64, uuencode, and quoted-printable. - */ + // Allocate a buffer for the decoded data. The output buffer is slightly + // larger than the input buffer; this assumes that the decoded data + // will never be significantly larger than the encoded data. This is a + // safe assumption with base64, uuencode, and quoted-printable. *decoded = malloc(length + 32768); if (decoded == NULL) { return -1; @@ -373,7 +364,7 @@ static long parse_MimeHeaders(interesting_mime_headers *m, int buflen = 0; int i; - /* Learn interesting things from the headers */ + // Learn interesting things from the headers ptr = *pcontent_start; *header = '\0'; headerlen = 0; @@ -457,8 +448,7 @@ static long parse_MimeHeaders(interesting_mime_headers *m, } -static int IsAsciiEncoding(interesting_mime_headers *m) -{ +static int IsAsciiEncoding(interesting_mime_headers *m) { if ((m->b[encoding].len != 0) && (strcasecmp(m->b[encoding].Key, "base64") == 0)) @@ -482,18 +472,14 @@ static char *FindNextContent(char *ptr, tmp = *content_end; *content_end = '\0'; - /** - * ok, if we have a content length of the mime part, - * try skipping the content on the search for the next - * boundary. since we don't trust the content_length - * 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.. - */ + // ok, if we have a content length of the mime part, + // try skipping the content on the search for the next + // boundary. since we don't trust the content_length + // 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)) - { + if ((SubMimeHeaders->content_length != -1) && (SubMimeHeaders->content_length > 10)) { char *pptr; long lines; @@ -508,32 +494,24 @@ static char *FindNextContent(char *ptr, } else { char *srch; - /** - * ok, if we have a content length of the mime part, - * 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.. - */ + // ok, if we have a content length of the mime part, + // 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)) - { + if ((SubMimeHeaders->content_length != -1) && (SubMimeHeaders->content_length > 10)) { char *pptr; pptr = ptr + SubMimeHeaders->content_length - 10; if (pptr < content_end) ptr = pptr; } - srch = next_boundary = NULL; for (srch = memchr(ptr, '-', content_end - ptr); (srch != NULL) && (srch < content_end); srch = memchr(srch, '-', content_end - srch)) { - if (!memcmp(srch, - m->b[startary].Key, - m->b[startary].len)) - { + if (!memcmp(srch, m->b[startary].Key, m->b[startary].len)) { next_boundary = srch; srch = content_end; } @@ -545,12 +523,11 @@ static char *FindNextContent(char *ptr, return next_boundary; } -/* - * Break out the components of a multipart message - * (This function expects to be fed HEADERS + CONTENT) - * 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. - */ + +// Break out the components of a multipart message +// (This function expects to be fed HEADERS + CONTENT) +// 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, @@ -572,12 +549,12 @@ static void recurseable_mime_parser(char *partnum, CBufStr *chosen_name; - /* If this is a multipart message, then recursively process it */ + // If this is a multipart message, then recursively process it ptr = content_start; part_start = NULL; if (m->is_multipart) { - /* Tell the client about this message's multipartedness */ + // Tell the client about this message's multipartedness if (PreMultiPartCallBack != NULL) { PreMultiPartCallBack("", "", @@ -592,16 +569,21 @@ static void recurseable_mime_parser(char *partnum, userdata); } - /* Figure out where the boundaries are */ + // Figure out where the boundaries are m->b[startary].len = snprintf(m->b[startary].Key, SIZ, "--%s", m->b[boundary].Key); SubMimeHeaders = InitInterestingMimes (); - while ((*ptr == '\r') || (*ptr == '\n')) ptr ++; + while ((*ptr == '\r') || (*ptr == '\n')) { + ptr++; + } - if (strncmp(ptr, m->b[startary].Key, m->b[startary].len) == 0) + if (strncmp(ptr, m->b[startary].Key, m->b[startary].len) == 0) { ptr += m->b[startary].len; + } - while ((*ptr == '\r') || (*ptr == '\n')) ptr ++; + while ((*ptr == '\r') || (*ptr == '\n')) { + ptr ++; + } part_start = NULL; do { @@ -624,9 +606,9 @@ static void recurseable_mime_parser(char *partnum, if ( (part_start != NULL) && (next_boundary != NULL) ) { part_end = next_boundary; - --part_end; /* omit the trailing LF */ + --part_end; // omit the trailing LF if (crlf_in_use) { - --part_end; /* omit the trailing CR */ + --part_end; // omit the trailing CR } if (!IsEmptyStr(partnum)) { @@ -652,17 +634,16 @@ 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 we pass out of scope, don't attempt to read past the end boundary. if ((*(next_boundary + m->b[startary].len) == '-') && (*(next_boundary + m->b[startary].len + 1) == '-') ){ ptr = content_end; } else { - /* Set up for the next part. */ + // Set up for the next part. part_start = strstr(next_boundary, "\n"); - /* Determine whether newlines are LF or CRLF */ + // Determine whether newlines are LF or CRLF evaluate_crlf_ptr = part_start; --evaluate_crlf_ptr; if ((*evaluate_crlf_ptr == '\r') && (*(evaluate_crlf_ptr + 1) == '\n')) { @@ -672,13 +653,13 @@ static void recurseable_mime_parser(char *partnum, crlf_in_use = 0; } - /* Advance past the LF ... now we're in the next part */ + // Advance past the LF ... now we're in the next part ++part_start; ptr = part_start; } } else { - /* Invalid end of multipart. Bail out! */ + // Invalid end of multipart. Bail out! ptr = content_end; } FlushInterestingMimes(SubMimeHeaders); @@ -699,7 +680,8 @@ static void recurseable_mime_parser(char *partnum, m->b[id].Key, userdata); } - } /* If it's not a multipart message, then do something with it */ + } + // If it's not a multipart message, then do something with it else { size_t length; part_start = ptr; @@ -804,12 +786,11 @@ static void recurseable_mime_parser(char *partnum, } -/* - * Break out the components of a multipart message - * (This function expects to be fed HEADERS + CONTENT) - * 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. - */ + +// Break out the components of a multipart message +// (This function expects to be fed HEADERS + CONTENT) +// 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. void the_mime_parser(char *partnum, char *content_start, char *content_end, MimeParserCallBackType CallBack, @@ -820,15 +801,14 @@ void the_mime_parser(char *partnum, { interesting_mime_headers *m; - /* If the caller didn't supply an endpointer, generate one by measure */ + // If the caller didn't supply an endpointer, generate one by measure if (content_end == NULL) { content_end = &content_start[strlen(content_start)]; } m = InitInterestingMimes(); - if (!parse_MimeHeaders(m, &content_start, content_end)) - { + if (!parse_MimeHeaders(m, &content_start, content_end)) { recurseable_mime_parser(partnum, content_start, content_end, @@ -843,12 +823,10 @@ void the_mime_parser(char *partnum, } -/* - * Entry point for the MIME parser. - * (This function expects to be fed HEADERS + CONTENT) - * 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. - */ +// Entry point for the MIME parser. +// (This function expects to be fed HEADERS + CONTENT) +// 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. void mime_parser(char *content_start, char *content_end, MimeParserCallBackType CallBack, @@ -857,7 +835,6 @@ void mime_parser(char *content_start, void *userdata, int dont_decode) { - the_mime_parser("", content_start, content_end, CallBack, PreMultiPartCallBack, @@ -866,10 +843,6 @@ void mime_parser(char *content_start, } - - - - typedef struct _MimeGuess { const char *Pattern; size_t PatternLen; @@ -905,12 +878,10 @@ MimeGuess MyMimes [] = { }; -const char *GuessMimeType(const char *data, size_t dlen) -{ +const char *GuessMimeType(const char *data, size_t dlen) { int MimeIndex = 0; - while (MyMimes[MimeIndex].PatternLen != 0) - { + while (MyMimes[MimeIndex].PatternLen != 0) { if ((MyMimes[MimeIndex].PatternLen + MyMimes[MimeIndex].PatternOffset < dlen) && strncmp(MyMimes[MimeIndex].Pattern, @@ -929,9 +900,8 @@ const char *GuessMimeType(const char *data, size_t dlen) } -const char* GuessMimeByFilename(const char *what, size_t len) -{ - /* we know some hardcoded on our own, try them... */ +const char* GuessMimeByFilename(const char *what, size_t len) { + // we know some hardcoded on our own, try them... if ((len > 3) && !strncasecmp(&what[len - 4], ".gif", 4)) return "image/gif"; else if ((len > 2) && !strncasecmp(&what[len - 3], ".js", 3)) @@ -967,7 +937,7 @@ const char* GuessMimeByFilename(const char *what, size_t len) else if ((len > 4) && !strncasecmp(&what[len - 5], ".wbmp", 5)) return "image/vnd.wap.wbmp"; else - /* and let xdgmime do the fallback. */ + // and let xdgmime do the fallback. return xdg_mime_get_mime_type_from_file_name(what); } @@ -980,31 +950,18 @@ struct IconName { char *FileName; }; -static void DeleteIcon(void *IconNamePtr) -{ + +static void DeleteIcon(void *IconNamePtr) { IconName *Icon = (IconName*) IconNamePtr; free(Icon->FlatName); free(Icon->FileName); free(Icon); } -/* -static const char *PrintFlat(void *IconNamePtr) -{ - IconName *Icon = (IconName*) IconNamePtr; - return Icon->FlatName; -} -static const char *PrintFile(void *IconNamePtr) -{ - IconName *Icon = (IconName*) IconNamePtr; - return Icon->FileName; -} -*/ #define GENSTR "x-generic" #define IGNORE_PREFIX_1 "gnome-mime" -int LoadIconDir(const char *DirName) -{ +int LoadIconDir(const char *DirName) { DIR *filedir = NULL; struct dirent *filedir_entry; int d_namelen; @@ -1017,8 +974,7 @@ int LoadIconDir(const char *DirName) return 0; } - while ((filedir_entry = readdir(filedir))) - { + while ((filedir_entry = readdir(filedir))) { char *MinorPtr; char *PStart; #ifdef _DIRENT_HAVE_D_NAMLEN @@ -1050,41 +1006,39 @@ int LoadIconDir(const char *DirName) Icon->FlatName = malloc(d_without_ext + 1); memcpy(Icon->FlatName, PStart, d_without_ext); Icon->FlatName[d_without_ext] = '\0'; - /* Try to find Minor type in image-jpeg */ + // Try to find Minor type in image-jpeg MinorPtr = strchr(Icon->FlatName, '-'); if (MinorPtr != NULL) { size_t MinorLen; MinorLen = 1 + d_without_ext - (MinorPtr - Icon->FlatName + 1); if ((MinorLen == sizeof(GENSTR)) && (strncmp(MinorPtr + 1, GENSTR, sizeof(GENSTR)) == 0)) { - /* ok, we found a generic filename. cut the generic. */ + // ok, we found a generic filename. cut the generic. *MinorPtr = '\0'; d_without_ext = d_without_ext - (MinorPtr - Icon->FlatName); } - else { /* Map the major / minor separator to / */ + else { // Map the major / minor separator to / *MinorPtr = '/'; } } -// PrintHash(IconHash, PrintFlat, PrintFile); -// printf("%s - %s\n", Icon->FlatName, Icon->FileName); Put(IconHash, Icon->FlatName, d_without_ext, Icon, DeleteIcon); -// PrintHash(IconHash, PrintFlat, PrintFile); } closedir(filedir); return 1; } -const char *GetIconFilename(char *MimeType, size_t len) -{ + +const char *GetIconFilename(char *MimeType, size_t len) { void *vIcon; IconName *Icon; - if(IconHash == NULL) + if (IconHash == NULL) { return NULL; + } GetHash(IconHash, MimeType, len, &vIcon), Icon = (IconName*) vIcon; - /* didn't find the exact mimetype? try major only. */ + // didn't find the exact mimetype? try major only. if (Icon == NULL) { char * pMinor; pMinor = strchr(MimeType, '/'); @@ -1098,11 +1052,10 @@ const char *GetIconFilename(char *MimeType, size_t len) return NULL; } - /*printf("Getting: [%s] == [%s] -> [%s]\n", MimeType, Icon->FlatName, Icon->FileName);*/ return Icon->FileName; } -void ShutDownLibCitadelMime(void) -{ + +void ShutDownLibCitadelMime(void) { DeleteHash(&IconHash); } -- 2.30.2