"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/lib-mail/test-message-header-parser.c" between
dovecot-2.3.16.tar.gz and dovecot-2.3.17.tar.gz

About: Dovecot is an IMAP and POP3 server, written with security primarily in mind.

test-message-header-parser.c  (dovecot-2.3.16):test-message-header-parser.c  (dovecot-2.3.17)
/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */ /* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
#include "lib.h" #include "lib.h"
#include "str.h" #include "str.h"
#include "strfuncs.h"
#include "unichar.h" #include "unichar.h"
#include "istream.h" #include "istream.h"
#include "message-size.h" #include "message-size.h"
#include "message-header-parser.h" #include "message-header-parser.h"
#include "test-common.h" #include "test-common.h"
#define TEST1_MSG_BODY_LEN 5 #define TEST1_MSG_BODY_LEN 5
static const char *test1_msg = static const char *test1_msg =
"h1: v1\n" "h1: v1\n"
"h2:\n" "h2:\n"
" v2\r\n" " v2\r\n"
"h3: \r\n" "h3: \r\n"
"\tv3\n" "\tv3\n"
"\tw3\r\n" "\tw3\r\n"
"h4: \r\n"
"\n" "\n"
" body"; " body";
static void static void
test_message_header_parser_one(struct message_header_parser_ctx *parser, test_message_header_parser_one(struct message_header_parser_ctx *parser,
enum message_header_parser_flags hdr_flags) enum message_header_parser_flags hdr_flags)
{ {
struct message_header_line *hdr; struct message_header_line *hdr;
bool use_full_value; bool use_full_value;
skipping to change at line 119 skipping to change at line 121
memcmp(hdr->full_value, " v3 w3", 6) == 0); memcmp(hdr->full_value, " v3 w3", 6) == 0);
} else if ((hdr_flags & MESSAGE_HEADER_PARSER_FLAG_DROP_CR) != 0) { } else if ((hdr_flags & MESSAGE_HEADER_PARSER_FLAG_DROP_CR) != 0) {
test_assert(hdr->full_value_len == 8 && test_assert(hdr->full_value_len == 8 &&
memcmp(hdr->full_value, "\n\tv3\n\tw3", 8) == 0); memcmp(hdr->full_value, "\n\tv3\n\tw3", 8) == 0);
} else if (use_full_value) { } else if (use_full_value) {
test_assert(hdr->full_value_len == 9 && test_assert(hdr->full_value_len == 9 &&
memcmp(hdr->full_value, "\r\n\tv3\n\tw3", 9) == 0); memcmp(hdr->full_value, "\r\n\tv3\n\tw3", 9) == 0);
} }
test_assert(message_parse_header_next(parser, &hdr) > 0); test_assert(message_parse_header_next(parser, &hdr) > 0);
test_assert(hdr->name_offset == 32 && hdr->full_value_offset == 32); test_assert(hdr->name_offset == 32 && hdr->full_value_offset == 36);
test_assert(hdr->name_len == 2 && strcmp(hdr->name, "h4") == 0);
test_assert(hdr->middle_len == 2 && memcmp(hdr->middle, ": ", 2) == 0);
test_assert(hdr->value_len == 0 && memcmp(hdr->value, "", 0) == 0);
test_assert(!hdr->continues && !hdr->continued && !hdr->eoh &&
!hdr->no_newline && hdr->crlf_newline);
test_assert(hdr->full_value_len == 0 && hdr->full_value != NULL);
test_assert(message_parse_header_next(parser, &hdr) > 0);
test_assert(hdr->name_offset == 38 && hdr->full_value_offset == 38);
test_assert(hdr->name_len == 0 && hdr->middle_len == 0 && hdr->value_len == 0); test_assert(hdr->name_len == 0 && hdr->middle_len == 0 && hdr->value_len == 0);
test_assert(!hdr->continues && !hdr->continued && hdr->eoh && test_assert(!hdr->continues && !hdr->continued && hdr->eoh &&
!hdr->no_newline && !hdr->crlf_newline); !hdr->no_newline && !hdr->crlf_newline);
test_assert(message_parse_header_next(parser, &hdr) < 0); test_assert(message_parse_header_next(parser, &hdr) < 0);
} }
static void test_message_header_parser(void) static void test_message_header_parser(void)
{ {
static enum message_header_parser_flags max_hdr_flags = static enum message_header_parser_flags max_hdr_flags =
skipping to change at line 238 skipping to change at line 249
message_parse_header_deinit(&parser); message_parse_header_deinit(&parser);
i_stream_seek(input, 0); i_stream_seek(input, 0);
/* Buffer must be +1 for message_get_header_size as it's using /* Buffer must be +1 for message_get_header_size as it's using
i_stream_read_bytes which does not work with lower buffersize i_stream_read_bytes which does not work with lower buffersize
because it returns -2 (input buffer full) if 2 bytes are wanted. */ because it returns -2 (input buffer full) if 2 bytes are wanted. */
test_istream_set_max_buffer_size(input, buffer_size+1); test_istream_set_max_buffer_size(input, buffer_size+1);
message_get_header_size(input, size_2_r, &has_nuls); message_get_header_size(input, size_2_r, &has_nuls);
i_stream_unref(&input); i_stream_unref(&input);
} }
#define NAME10 "1234567890"
#define NAME100 NAME10 NAME10 NAME10 NAME10 NAME10 \
NAME10 NAME10 NAME10 NAME10 NAME10
#define NAME1000 NAME100 NAME100 NAME100 NAME100 NAME100 \
NAME100 NAME100 NAME100 NAME100 NAME100
static void test_message_header_parser_long_lines(void) static void test_message_header_parser_long_lines(void)
{ {
static const char *lf_str = "1234567890: 345\n\n"; static const char *lf_str = NAME10": 345\n\n";
static const char *crlf_str = "1234567890: 345\r\n\r\n"; static const char *crlf_str = NAME10": 345\r\n\r\n";
static const char *lf_str_vl = NAME1000": Is a long header name\n\n";
static const char *crlf_str_vl = NAME1000": Is a long header name\r\n\r\n
";
static const char *lf_str_ol = NAME1000 \
NAME100 ": Is a overlong header name\n\n";
static const char *crlf_str_ol = NAME1000 \
NAME100 ": Is a overlong header name\r\n\r\n";
struct message_size hdr_size, hdr_size2; struct message_size hdr_size, hdr_size2;
size_t i, len; size_t i, len;
test_begin("message header parser long lines"); test_begin("message header parser long lines");
len = strlen(lf_str); len = strlen(lf_str);
for (i = 2; i < len; i++) { for (i = 2; i < len; i++) {
test_message_header_parser_long_lines_str(lf_str, i, &hdr_size, & hdr_size2); test_message_header_parser_long_lines_str(lf_str, i, &hdr_size, & hdr_size2);
test_assert(hdr_size.physical_size == len); test_assert(hdr_size.physical_size == len);
test_assert(hdr_size.virtual_size == len + 2); test_assert(hdr_size.virtual_size == len + 2);
test_assert(hdr_size.virtual_size == hdr_size2.virtual_size); test_assert(hdr_size.virtual_size == hdr_size2.virtual_size);
test_assert(hdr_size.physical_size == hdr_size2.physical_size); test_assert(hdr_size.physical_size == hdr_size2.physical_size);
} }
len = strlen(crlf_str); len = strlen(crlf_str);
for (i = 3; i < len; i++) { for (i = 3; i < len; i++) {
test_message_header_parser_long_lines_str(crlf_str, i, &hdr_size, &hdr_size2); test_message_header_parser_long_lines_str(crlf_str, i, &hdr_size, &hdr_size2);
test_assert(hdr_size.physical_size == len); test_assert(hdr_size.physical_size == len);
test_assert(hdr_size.virtual_size == len); test_assert(hdr_size.virtual_size == len);
test_assert(hdr_size.virtual_size == hdr_size2.virtual_size); test_assert(hdr_size.virtual_size == hdr_size2.virtual_size);
test_assert(hdr_size.physical_size == hdr_size2.physical_size); test_assert(hdr_size.physical_size == hdr_size2.physical_size);
} }
/* increment these faster, otherwise the test is very slow */
len = strlen(lf_str_vl);
for (i = 3; i < len; i *= 2) {
test_message_header_parser_long_lines_str(lf_str_vl, i, &hdr_siz
e, &hdr_size2);
test_assert(hdr_size.physical_size == len);
test_assert(hdr_size.virtual_size == len + 2);
test_assert(hdr_size.virtual_size == hdr_size2.virtual_size);
test_assert(hdr_size.physical_size == hdr_size2.physical_size);
}
len = strlen(crlf_str_vl);
for (i = 3; i < len; i *= 2) {
test_message_header_parser_long_lines_str(crlf_str_vl, i, &hdr_si
ze, &hdr_size2);
test_assert(hdr_size.physical_size == len);
test_assert(hdr_size.virtual_size == len);
test_assert(hdr_size.virtual_size == hdr_size2.virtual_size);
test_assert(hdr_size.physical_size == hdr_size2.physical_size);
}
/* test that parsing overlength lines work so that name & middle are
empty. */
struct message_header_line *hdr;
struct message_header_parser_ctx *ctx;
struct istream *input;
input = test_istream_create(lf_str_ol);
ctx = message_parse_header_init(input, NULL, 0);
test_assert(message_parse_header_next(ctx, &hdr) > 0 &&
*hdr->name == '\0' && hdr->middle == uchar_empty_ptr &&
hdr->name_len == 0 && hdr->middle_len == 0 &&
hdr->value != NULL && hdr->value_len > 0);
test_assert(message_parse_header_next(ctx, &hdr) > 0 &&
hdr->eoh);
message_parse_header_deinit(&ctx);
i_stream_unref(&input);
input = test_istream_create(crlf_str_ol);
ctx = message_parse_header_init(input, NULL, 0);
test_assert(message_parse_header_next(ctx, &hdr) > 0 &&
*hdr->name == '\0' && hdr->middle == uchar_empty_ptr &&
hdr->name_len == 0 && hdr->middle_len == 0 &&
hdr->value != NULL && hdr->value_len > 0);
test_assert(message_parse_header_next(ctx, &hdr) > 0 &&
hdr->eoh);
message_parse_header_deinit(&ctx);
i_stream_unref(&input);
/* test offset parsing */
static const char *data = "h1" NAME1000 NAME100 \
": value1\r\n" \
"h2" NAME1000 NAME100 \
": value2\r\n" \
"h3" NAME1000 NAME100 \
": value3\r\n\r\n";
input = test_istream_create(data);
ctx = message_parse_header_init(input, NULL, 0);
test_assert(message_parse_header_next(ctx, &hdr) > 0 &&
hdr->full_value[0] == 'h' &&
hdr->full_value[1] == '1' &&
hdr->full_value_offset == 0);
test_assert(message_parse_header_next(ctx, &hdr) > 0 &&
hdr->full_value[0] == 'h' &&
hdr->full_value[1] == '2' &&
hdr->full_value_offset == 1112);
test_assert(message_parse_header_next(ctx, &hdr) > 0 &&
hdr->full_value[0] == 'h' &&
hdr->full_value[1] == '3' &&
hdr->full_value_offset == 2224);
test_assert(message_parse_header_next(ctx, &hdr) > 0 &&
hdr->eoh);
message_parse_header_deinit(&ctx);
i_stream_unref(&input);
test_end(); test_end();
} }
static void test_message_header_parser_extra_cr_in_eoh(void) static void test_message_header_parser_extra_cr_in_eoh(void)
{ {
static const char *str = "a:b\n\r\r\n"; static const char *str = "a:b\n\r\r\n";
struct message_header_parser_ctx *parser; struct message_header_parser_ctx *parser;
struct message_header_line *hdr; struct message_header_line *hdr;
struct istream *input; struct istream *input;
test_begin("message header parser extra CR in EOH"); test_begin("message header parser extra CR in EOH");
input = test_istream_create(str); input = test_istream_create(str);
parser = message_parse_header_init(input, NULL, 0); parser = message_parse_header_init(input, NULL, 0);
test_assert(message_parse_header_next(parser, &hdr) > 0 && test_assert(message_parse_header_next(parser, &hdr) > 0 &&
strcmp(hdr->name, "a") == 0); strcmp(hdr->name, "a") == 0);
test_assert(message_parse_header_next(parser, &hdr) > 0 && test_assert(message_parse_header_next(parser, &hdr) > 0 &&
strcmp(hdr->name, "\r") == 0 && hdr->middle_len == 0 && *hdr->value == '\r' && hdr->value_len == 1 &&
hdr->value_len == 0 && !hdr->eoh); hdr->full_value_offset == 4 &&
hdr->middle_len == 0 &&
hdr->name_len == 0 && !hdr->eoh);
test_assert(message_parse_header_next(parser, &hdr) < 0); test_assert(message_parse_header_next(parser, &hdr) < 0);
message_parse_header_deinit(&parser); message_parse_header_deinit(&parser);
test_assert(input->stream_errno == 0); test_assert(input->stream_errno == 0);
i_stream_unref(&input); i_stream_unref(&input);
test_end(); test_end();
} }
static void test_message_header_parser_no_eoh(void) static void test_message_header_parser_no_eoh(void)
{ {
static const char *str = "a:b\n"; static const char *str = "a:b\n";
skipping to change at line 335 skipping to change at line 437
test_assert_strcmp(message_header_strdup(pool_datastack_create(), test_assert_strcmp(message_header_strdup(pool_datastack_create(),
hdr->value, hdr->value_len), hdr->value, hdr->value_len),
UNICODE_REPLACEMENT_CHAR_UTF8 UNICODE_REPLACEMENT_CHAR _UTF8"b"); UNICODE_REPLACEMENT_CHAR_UTF8 UNICODE_REPLACEMENT_CHAR _UTF8"b");
test_assert(message_parse_header_next(parser, &hdr) < 0); test_assert(message_parse_header_next(parser, &hdr) < 0);
message_parse_header_deinit(&parser); message_parse_header_deinit(&parser);
test_assert(input->stream_errno == 0); test_assert(input->stream_errno == 0);
i_stream_unref(&input); i_stream_unref(&input);
test_end(); test_end();
} }
static void test_message_header_parser_extra_crlf_in_name(void)
{
static const unsigned char str[] = "X-Header\r\n Name: Header Value\n\n"
;
struct message_header_parser_ctx *parser;
struct message_header_line *hdr;
struct istream *input;
test_begin("message header parser CRLF in header name");
input = test_istream_create_data(str, sizeof(str)-1);
parser = message_parse_header_init(input, NULL, 0);
hdr = NULL;
test_assert(message_parse_header_next(parser, &hdr) > 0 &&
*hdr->name == '\0' && hdr->middle == uchar_empty_ptr &&
hdr->name_len == 0 && hdr->middle_len == 0 &&
hdr->value != NULL && hdr->value_len > 0);
test_assert(message_parse_header_next(parser, &hdr) > 0 &&
*hdr->name == '\0' && hdr->middle == uchar_empty_ptr &&
hdr->name_len == 0 && hdr->middle_len == 0 &&
hdr->value != NULL && hdr->value_len > 0 &&
hdr->continued);
test_assert(message_parse_header_next(parser, &hdr) > 0 &&
hdr->eoh);
message_parse_header_deinit(&parser);
i_stream_unref(&input);
test_end();
}
int main(void) int main(void)
{ {
static void (*const test_functions[])(void) = { static void (*const test_functions[])(void) = {
test_message_header_parser, test_message_header_parser,
test_message_header_parser_partial, test_message_header_parser_partial,
test_message_header_parser_long_lines, test_message_header_parser_long_lines,
test_message_header_parser_extra_cr_in_eoh, test_message_header_parser_extra_cr_in_eoh,
test_message_header_parser_no_eoh, test_message_header_parser_no_eoh,
test_message_header_parser_nul, test_message_header_parser_nul,
test_message_header_parser_extra_crlf_in_name,
NULL NULL
}; };
return test_run(test_functions); return test_run(test_functions);
} }
 End of changes. 9 change blocks. 
5 lines changed or deleted 141 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)