Mercurial > dovecot > core-2.2
changeset 10207:ee3f9bc4f5b7 HEAD
message header parser: Fixed parsing lines larger than input buffer.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 27 Oct 2009 16:04:22 -0400 |
parents | 86110f830311 |
children | 233cda69b00a |
files | src/lib-mail/message-header-parser.c src/lib-mail/test-message-header-parser.c |
diffstat | 2 files changed, 54 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-mail/message-header-parser.c Tue Oct 27 13:49:17 2009 -0400 +++ b/src/lib-mail/message-header-parser.c Tue Oct 27 16:04:22 2009 -0400 @@ -107,7 +107,7 @@ return -1; } - if (size > 0 && + if (size > 0 && !ctx->skip_line && (msg[0] == '\n' || (msg[0] == '\r' && size > 1 && msg[1] == '\n'))) { /* end of headers - this mostly happens just @@ -172,7 +172,7 @@ if (msg[i] > ':') continue; - if (msg[i] == ':') { + if (msg[i] == ':' && !ctx->skip_line) { colon_pos = i; line->full_value_offset = ctx->input->v_offset + i + 1; @@ -203,20 +203,19 @@ if (i < parse_size) { /* got a line */ if (ctx->skip_line) { - /* skipping a huge line */ + /* skipping a line with a huge header name */ if (ctx->hdr_size != NULL) { - ctx->hdr_size->physical_size += i; - ctx->hdr_size->virtual_size += i; + ctx->hdr_size->lines++; + ctx->hdr_size->physical_size += i + 1; + ctx->hdr_size->virtual_size += i + 1; } - if (i == 0 || msg[i-1] != '\r') { /* missing CR */ if (ctx->hdr_size != NULL) ctx->hdr_size->virtual_size++; - } else { - crlf_newline = TRUE; } - i_stream_skip(ctx->input, i); + + i_stream_skip(ctx->input, i + 1); startpos = 0; ctx->skip_line = FALSE; continue;
--- a/src/lib-mail/test-message-header-parser.c Tue Oct 27 13:49:17 2009 -0400 +++ b/src/lib-mail/test-message-header-parser.c Tue Oct 27 16:04:22 2009 -0400 @@ -194,11 +194,57 @@ test_end(); } +static void +test_message_header_parser_long_lines_str(const char *str, + unsigned int buffer_size, + struct message_size *size_r) +{ + struct message_header_parser_ctx *parser; + struct message_header_line *hdr; + struct istream *input; + unsigned int i, len = strlen(str); + + input = test_istream_create(str); + test_istream_set_max_buffer_size(input, buffer_size); + + parser = message_parse_header_init(input, size_r, 0); + for (i = 1; i <= len; i++) { + test_istream_set_size(input, i); + while (message_parse_header_next(parser, &hdr) > 0) ; + } + message_parse_header_deinit(&parser); + i_stream_unref(&input); +} + +static void test_message_header_parser_long_lines(void) +{ + static const char *lf_str = "1234567890: 345\n\n"; + static const char *crlf_str = "1234567890: 345\r\n\r\n"; + struct message_size hdr_size; + unsigned int i, len; + + test_begin("message header parser long lines"); + len = strlen(lf_str); + for (i = 1; i < len; i++) { + test_message_header_parser_long_lines_str(lf_str, i, &hdr_size); + test_assert(hdr_size.physical_size == len); + test_assert(hdr_size.virtual_size == len + 2); + } + len = strlen(crlf_str); + for (i = 1; i < len; i++) { + test_message_header_parser_long_lines_str(crlf_str, i, &hdr_size); + test_assert(hdr_size.physical_size == len); + test_assert(hdr_size.virtual_size == len); + } + test_end(); +} + int main(void) { static void (*test_functions[])(void) = { test_message_header_parser, test_message_header_parser_partial, + test_message_header_parser_long_lines, NULL }; return test_run(test_functions);