static void
parse_mime_parameters(struct rfc822_parser_context *parser,
pool_t pool, const struct message_part_param **params_r,
- unsigned int *params_count_r)
+ unsigned int *params_count_r,
+ struct message_part_data_limits *limits)
{
const char *const *results;
struct message_part_param *params;
i_assert((params_count % 2) == 0);
params_count /= 2;
+ if (params_count > limits->remaining_mime_params)
+ params_count = limits->remaining_mime_params;
+ limits->remaining_mime_params -= params_count;
+
if (params_count > 0) {
params = p_new(pool, struct message_part_param, params_count);
for (i = 0; i < params_count; i++) {
static void
parse_content_type(struct message_part_data *data,
- pool_t pool, struct message_header_line *hdr)
+ pool_t pool, struct message_header_line *hdr,
+ struct message_part_data_limits *limits)
{
struct rfc822_parser_context parser;
string_t *str;
parse_mime_parameters(&parser, pool,
&data->content_type_params,
- &data->content_type_params_count);
+ &data->content_type_params_count, limits);
rfc822_parser_deinit(&parser);
}
static void
parse_content_disposition(struct message_part_data *data,
- pool_t pool, struct message_header_line *hdr)
+ pool_t pool, struct message_header_line *hdr,
+ struct message_part_data_limits *limits)
{
struct rfc822_parser_context parser;
string_t *str;
parse_mime_parameters(&parser, pool,
&data->content_disposition_params,
- &data->content_disposition_params_count);
+ &data->content_disposition_params_count, limits);
rfc822_parser_deinit(&parser);
}
case 't':
case 'T':
if (strcasecmp(name, "Type") == 0 && data->content_type == NULL)
- parse_content_type(data, pool, hdr);
+ parse_content_type(data, pool, hdr, limits);
else if (strcasecmp(name, "Transfer-Encoding") == 0 &&
data->content_transfer_encoding == NULL)
parse_content_transfer_encoding(data, pool, hdr);
hdr->full_value_len);
else if (strcasecmp(name, "Disposition") == 0 &&
data->content_disposition_params == NULL)
- parse_content_disposition(data, pool, hdr);
+ parse_content_disposition(data, pool, hdr, limits);
break;
}
}
#define MESSAGE_PART_DATA_MAX_TOTAL_ADDRESSES 100000
#define MESSAGE_PART_DATA_MAX_TOTAL_LANGUAGE_TAGS 100000
+/* Combined limit for Content-Type + Content-Disposition parameters */
+#define MESSAGE_PART_DATA_MAX_TOTAL_MIME_PARAMS 200000
struct message_part_data_limits {
unsigned int remaining_addresses;
unsigned int remaining_language_tags;
+ unsigned int remaining_mime_params;
};
#define MESSAGE_PART_DATA_LIMITS_INIT \
{ MESSAGE_PART_DATA_MAX_TOTAL_ADDRESSES, \
- MESSAGE_PART_DATA_MAX_TOTAL_LANGUAGE_TAGS }
+ MESSAGE_PART_DATA_MAX_TOTAL_LANGUAGE_TAGS, \
+ MESSAGE_PART_DATA_MAX_TOTAL_MIME_PARAMS }
struct message_part_param {
const char *name;