From: Wilfried Göesgens Date: Sat, 18 Apr 2009 20:30:14 +0000 (+0000) Subject: * big profiling stuff: X-Git-Tag: v7.86~1244 X-Git-Url: https://code.citadel.org/?p=citadel.git;a=commitdiff_plain;h=351f7680b65e93cdd31ba6623d8b9c88175575f5 * big profiling stuff: * reduce strlen use wherever we can * reduce malloc usage * don't use sprintf --- diff --git a/libcitadel/lib/libcitadel.h b/libcitadel/lib/libcitadel.h index 59364fdcc..421979210 100644 --- a/libcitadel/lib/libcitadel.h +++ b/libcitadel/lib/libcitadel.h @@ -77,7 +77,7 @@ void ShutDownLibCitadel(void); * MIME parser declarations */ -void extract_key(char *target, char *source, char *key); +void extract_key(char *target, char *source, long sourcelen, char *key, long keylen); void mime_parser(char *content_start, char *content_end, void (*CallBack) @@ -336,7 +336,7 @@ size_t CtdlEncodeBase64(char *dest, const char *source, size_t sourcelen, int li int CtdlDecodeBase64(char *dest, const char *source, size_t length); unsigned int decode_hex(char *Source); int CtdlDecodeQuotedPrintable(char *decoded, char *encoded, int sourcelen); -void striplt(char *); +long striplt(char *); int haschar(const char *st, int ch); void remove_token(char *source, int parmnum, char separator); void fmt_date(char *buf, size_t n, time_t thetime, int seconds); @@ -353,6 +353,7 @@ char *CtdlTempFileName(char *prefix1, int prefix2); FILE *CtdlTempFile(void); void generate_uuid(char *buf); char *bmstrcasestr(char *text, char *pattern); +char *bmstrcasestr_len(char *text, size_t textlen, char *pattern, size_t patlen); void CtdlMakeTempFileName(char *name, int len); char *rfc2047encode(char *line, long length); int is_msg_in_mset(const char *mset, long msgnum); diff --git a/libcitadel/lib/mime_parser.c b/libcitadel/lib/mime_parser.c index 85f955c0c..3fdcf5835 100644 --- a/libcitadel/lib/mime_parser.c +++ b/libcitadel/lib/mime_parser.c @@ -24,20 +24,31 @@ #include "libcitadel.h" #include "libcitadellocal.h" -void extract_key(char *target, char *source, char *key) +void extract_key(char *target, char *source, long sourcelen, char *key, long keylen) { + char *lookat; char *ptr; - char looking_for[256]; + //char looking_for[256]; int double_quotes = 0; - snprintf(looking_for, sizeof looking_for, "%s=", key); + lookat = source; + //snprintf(looking_for, sizeof looking_for, "%s=", key); - ptr = bmstrcasestr(source, looking_for); + while ((lookat != NULL)) { + ptr = bmstrcasestr_len(lookat, sourcelen, key, keylen); + lookat = ptr; + if ((ptr != NULL) && + (*(ptr + keylen) == '=')) + lookat = NULL; + + + } + //ptr = bmstrcasestr(source, looking_for); if (ptr == NULL) { strcpy(target, ""); return; } - strcpy(target, (ptr + strlen(looking_for))); + strcpy(target, (ptr + keylen + 1)); for (ptr=target; (*ptr != 0); ++ptr) { @@ -57,6 +68,7 @@ void extract_key(char *target, char *source, char *key) } } } + *ptr = '\0'; } @@ -309,9 +321,11 @@ void the_mime_parser(char *partnum, char *next_boundary; char *content_type; char *charset; + size_t content_type_len; size_t content_length; char *encoding; char *disposition; + size_t disposition_len; char *id; char *name = NULL; char *content_type_name; @@ -330,41 +344,41 @@ void the_mime_parser(char *partnum, ptr = content_start; content_length = 0; - boundary = malloc(SIZ); - memset(boundary, 0, SIZ); + boundary = malloc(SIZ * 12); + *boundary = '\0'; - startary = malloc(SIZ); - memset(startary, 0, SIZ); + startary = boundary + SIZ * 1; + *startary = '\0'; - endary = malloc(SIZ); - memset(endary, 0, SIZ); + endary = boundary + SIZ * 2; + *endary = '\0'; - header = malloc(SIZ); - memset(header, 0, SIZ); + header = boundary + SIZ * 3; + *header = '\0'; - content_type = malloc(SIZ); - memset(content_type, 0, SIZ); + content_type = boundary + SIZ * 4; + *content_type = '\0'; - charset = malloc(SIZ); - memset(charset, 0, SIZ); + charset = boundary + SIZ * 5; + *charset = '\0'; - encoding = malloc(SIZ); - memset(encoding, 0, SIZ); + encoding = boundary + SIZ * 6; + *encoding = '\0'; - content_type_name = malloc(SIZ); - memset(content_type_name, 0, SIZ); + content_type_name = boundary + SIZ * 7; + *content_type_name = '\0'; - content_disposition_name = malloc(SIZ); - memset(content_disposition_name, 0, SIZ); + content_disposition_name = boundary + SIZ * 8; + *content_disposition_name = '\0'; - filename = malloc(SIZ); - memset(filename, 0, SIZ); + filename = boundary + SIZ * 9; + *filename = '\0'; - disposition = malloc(SIZ); - memset(disposition, 0, SIZ); + disposition = boundary + SIZ * 10; + *disposition = '\0'; - id = malloc(SIZ); - memset(id, 0, SIZ); + id = boundary + SIZ * 11; + *id = '\0'; /* If the caller didn't supply an endpointer, generate one by measure */ if (content_end == NULL) { @@ -388,11 +402,13 @@ void the_mime_parser(char *partnum, if (!isspace(buf[0])) { if (!strncasecmp(header, "Content-type:", 13)) { - strcpy(content_type, &header[13]); - striplt(content_type); - extract_key(content_type_name, content_type, "name"); - extract_key(charset, content_type, "charset"); - extract_key(boundary, header, "boundary"); + memcpy (content_type, &header[13], headerlen - 12); + content_type_len = striplt (content_type); + + extract_key(content_type_name, content_type, content_type_len, HKEY("name")); + extract_key(charset, content_type, content_type_len, HKEY("charset")); + extract_key(boundary, header, headerlen, HKEY("boundary")); + /* Deal with weird headers */ if (strchr(content_type, ' ')) *(strchr(content_type, ' ')) = '\0'; @@ -400,10 +416,10 @@ void the_mime_parser(char *partnum, *(strchr(content_type, ';')) = '\0'; } if (!strncasecmp(header, "Content-Disposition:", 20)) { - strcpy(disposition, &header[20]); - striplt(disposition); - extract_key(content_disposition_name, disposition, "name"); - extract_key(filename, disposition, "filename"); + memcpy (disposition, &header[20], headerlen - 19); + disposition_len = striplt(disposition); + extract_key(content_disposition_name, disposition, disposition_len, HKEY("name")); + extract_key(filename, disposition, disposition_len, HKEY("filename")); } if (!strncasecmp(header, "Content-ID:", 11)) { strcpy(id, &header[11]); @@ -455,9 +471,8 @@ void the_mime_parser(char *partnum, } /* Figure out where the boundaries are */ - snprintf(startary, SIZ, "--%s", boundary); + startary_len = snprintf(startary, SIZ, "--%s", boundary); snprintf(endary, SIZ, "--%s--", boundary); - startary_len = strlen(startary); part_start = NULL; do { @@ -618,17 +633,6 @@ void the_mime_parser(char *partnum, end_parser: /* free the buffers! end the oppression!! */ free(boundary); - free(startary); - free(endary); - free(header); - free(content_type); - free(charset); - free(encoding); - free(content_type_name); - free(content_disposition_name); - free(filename); - free(disposition); - free(id); } diff --git a/libcitadel/lib/tools.c b/libcitadel/lib/tools.c index a772bcade..6cb0646ea 100644 --- a/libcitadel/lib/tools.c +++ b/libcitadel/lib/tools.c @@ -460,22 +460,40 @@ char *rfc2047encode(char *line, long length) /* * Strip leading and trailing spaces from a string */ -void striplt(char *buf) +long striplt(char *buf) { - size_t len; - int a; + int CountTrail = 0; + int FromStart = 1; + char *aptr, *bptr; + + if ((buf==NULL) || (IsEmptyStr(buf))) + return 0; + + bptr = aptr = buf; + + while (!IsEmptyStr(aptr)) { + if (isspace(*aptr)) { + if (FromStart) + aptr ++; + else { + CountTrail ++; + *bptr = *aptr; + aptr++; bptr++; + } + } + else { + CountTrail = 0; + *bptr = *aptr; + aptr++; bptr++; + } + } - if (buf==NULL) return; - if (IsEmptyStr(buf)) return; - len = strlen(buf); - while ((!IsEmptyStr(buf)) && (isspace(buf[len - 1]))) - buf[--len] = 0; - if (IsEmptyStr(buf)) return; - a = 0; - while ((!IsEmptyStr(buf)) && (isspace(buf[a]))) - a++; - if (a > 0) - memmove(buf, &buf[a], len - a + 1); + if (CountTrail > 0) { + bptr -= CountTrail; + } + + *bptr = '\0'; + return bptr - buf; } @@ -767,21 +785,16 @@ void generate_uuid(char *buf) { * The code is roughly based on the strstr() replacement from 'tin' written * by Urs Jannsen. */ -char *bmstrcasestr(char *text, char *pattern) { +inline char *_bmstrcasestr_len(char *text, size_t textlen, char *pattern, size_t patlen) { register unsigned char *p, *t; register int i, j, *delta; register size_t p1; int deltaspace[256]; - size_t textlen; - size_t patlen; if (!text) return(NULL); if (!pattern) return(NULL); - textlen = strlen (text); - patlen = strlen (pattern); - /* algorithm fails if pattern is empty */ if ((p1 = patlen) == 0) return (text); @@ -823,7 +836,29 @@ char *bmstrcasestr(char *text, char *pattern) { return (NULL); } +/* + * bmstrcasestr() -- case-insensitive substring search + * + * This uses the Boyer-Moore search algorithm and is therefore quite fast. + * The code is roughly based on the strstr() replacement from 'tin' written + * by Urs Jannsen. + */ +char *bmstrcasestr(char *text, char *pattern) { + size_t textlen; + size_t patlen; + if (!text) return(NULL); + if (!pattern) return(NULL); + + textlen = strlen (text); + patlen = strlen (pattern); + + return _bmstrcasestr_len(text, textlen, pattern, patlen); +} + +char *bmstrcasestr_len(char *text, size_t textlen, char *pattern, size_t patlen) { + return _bmstrcasestr_len(text, textlen, pattern, patlen); +} /* * Local replacement for controversial C library function that generates