X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/c007c9748e22d0d518cf254f31504d4a7a4db1ee..93a6fce2ebf117f490d7ee11f066f75280d32386:/src/src/mime.c diff --git a/src/src/mime.c b/src/src/mime.c index 6a9e31a0a..51f00d368 100644 --- a/src/src/mime.c +++ b/src/src/mime.c @@ -283,10 +283,10 @@ return f; int -mime_decode(uschar **listptr) +mime_decode(const uschar **listptr) { int sep = 0; -uschar *list = *listptr; +const uschar *list = *listptr; uschar *option; uschar option_buffer[1024]; uschar decode_path[1024]; @@ -528,26 +528,24 @@ while(1) */ if (context != NULL) { - while(fgets(CS header, MIME_MAX_HEADER_SIZE, f) != NULL) + while(fgets(CS header, MIME_MAX_HEADER_SIZE, f)) { /* boundary line must start with 2 dashes */ - if (Ustrncmp(header,"--",2) == 0) - { - if (Ustrncmp((header+2),context->boundary,Ustrlen(context->boundary)) == 0) + if ( Ustrncmp(header, "--", 2) == 0 + && Ustrncmp(header+2, context->boundary, Ustrlen(context->boundary)) == 0) + { + /* found boundary */ + if (Ustrncmp((header+2+Ustrlen(context->boundary)), "--", 2) == 0) { - /* found boundary */ - if (Ustrncmp((header+2+Ustrlen(context->boundary)),"--",2) == 0) - { - /* END boundary found */ - debug_printf("End boundary found %s\n", context->boundary); - return rc; - } - else - debug_printf("Next part with boundary %s\n", context->boundary); - - /* can't use break here */ - goto DECODE_HEADERS; + /* END boundary found */ + debug_printf("End boundary found %s\n", context->boundary); + return rc; } + else + debug_printf("Next part with boundary %s\n", context->boundary); + + /* can't use break here */ + goto DECODE_HEADERS; } } /* Hit EOF or read error. Ugh. */ @@ -557,74 +555,96 @@ while(1) DECODE_HEADERS: /* parse headers, set up expansion variables */ - while (mime_get_header(f,header)) + while (mime_get_header(f, header)) { int i; /* loop through header list */ for (i = 0; i < mime_header_list_size; i++) - { - uschar *header_value = NULL; - int header_value_len = 0; - - /* found an interesting header? */ - if (strncmpic(mime_header_list[i].name,header,mime_header_list[i].namelen) == 0) - { - uschar *p = header + mime_header_list[i].namelen; - /* yes, grab the value (normalize to lower case) - and copy to its corresponding expansion variable */ + if (strncmpic(mime_header_list[i].name, + header, mime_header_list[i].namelen) == 0) + { /* found an interesting header */ + uschar * header_value; + int header_value_len; + uschar * p = header + mime_header_list[i].namelen; + + /* grab the value (normalize to lower case) + and copy to its corresponding expansion variable */ while(*p != ';') { *p = tolower(*p); p++; } - header_value_len = (p - (header + mime_header_list[i].namelen)); - header_value = (uschar *)malloc(header_value_len+1); - memset(header_value,0,header_value_len+1); + header_value_len = p - (header + mime_header_list[i].namelen); p = header + mime_header_list[i].namelen; - Ustrncpy(header_value, p, header_value_len); - debug_printf("Found %s MIME header, value is '%s'\n", mime_header_list[i].name, header_value); + header_value = string_copyn(p, header_value_len); + debug_printf("Found %s MIME header, value is '%s'\n", + mime_header_list[i].name, header_value); *((uschar **)(mime_header_list[i].value)) = header_value; /* make p point to the next character after the closing ';' */ - p += (header_value_len+1); + p += header_value_len+1; - /* grab all param=value tags on the remaining line, check if they are interesting */ + /* grab all param=value tags on the remaining line, + check if they are interesting */ NEXT_PARAM_SEARCH: - while (*p != 0) + while (*p) { + /* debug_printf(" considering paramlist '%s'\n", p); */ mime_parameter * mp; for (mp = mime_parameter_list; mp < &mime_parameter_list[mime_parameter_list_size]; mp++) { - uschar *param_value = NULL; - int param_value_len = 0; + uschar * param_value = NULL; /* found an interesting parameter? */ - if (strncmpic(mp->name, p,mp->namelen) == 0) + if (strncmpic(mp->name, p, mp->namelen) == 0) { - uschar *q = p + mp->namelen; + int size = 0; + int ptr = 0; + /* yes, grab the value and copy to its corresponding expansion variable */ - while(*q != ';') q++; - param_value_len = (q - (p + mp->namelen)); - param_value = (uschar *)malloc(param_value_len+1); - memset(param_value,0,param_value_len+1); - q = p + mp->namelen; - Ustrncpy(param_value, q, param_value_len); - param_value = rfc2047_decode(param_value, check_rfc2047_length, NULL, 32, ¶m_value_len, &q); - debug_printf("Found %s MIME parameter in %s header, value is '%s'\n", mp->name, mime_header_list[i].name, param_value); - *((uschar **)(mp->value)) = param_value; - p += (mp->namelen + param_value_len + 1); + p += mp->namelen; + while(*p && *p != ';') /* ; terminates */ + if (*p == '"') + { + p++; /* skip leading " */ + while(*p && *p != '"') /* " protects ; */ + param_value = string_cat(param_value, &size, &ptr, p++, 1); + if (*p) p++; /* skip trailing " */ + } + else + param_value = string_cat(param_value, &size, &ptr, p++, 1); + if (*p) p++; /* skip trailing ; */ + + if (param_value) + { + uschar * dummy; + param_value[ptr++] = '\0'; + + param_value = rfc2047_decode(param_value, + check_rfc2047_length, NULL, 32, NULL, &dummy); + debug_printf(" Found %s MIME parameter in %s header, " + "value is '%s'\n", mp->name, mime_header_list[i].name, + param_value); + } + *mp->value = param_value; goto NEXT_PARAM_SEARCH; } } - /* There is something, but not one of our interesting parameters. - Advance to the next semicolon */ - while(*p != ';') p++; - p++; + /* There is something, but not one of our interesting parameters. + Advance to the next unquoted semicolon */ + while(*p && *p != ';') + if (*p == '"') + { + while(*++p && *p != '"') ; + if (*p) p++; + } + else + p++; + if (*p) p++; } } - } } /* set additional flag variables (easier access) */ @@ -676,7 +696,7 @@ NEXT_PARAM_SEARCH: else if ( (mime_content_type != NULL) && (Ustrncmp(mime_content_type,"message/rfc822",14) == 0) ) { - uschar *rfc822name = NULL; + const uschar *rfc822name = NULL; uschar filename[2048]; int file_nr = 0; int result = 0;