test-message-header-parser.c revision 2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74c
a8c5a86d183db25a57bf193c06b41e092ec2e151Timo Sirainen/* Copyright (c) 2007-2016 Dovecot authors, see the included COPYING file */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "lib.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "str.h"
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen#include "istream.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "message-size.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "message-header-parser.h"
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen#include "test-common.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen#define TEST1_MSG_BODY_LEN 5
905457e0982fc15930d90e174f271dc69f9afcf9Timo Sirainenstatic const char *test1_msg =
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen "h1: v1\n"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen "h2:\n"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen " v2\r\n"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen "h3: \r\n"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen "\tv3\n"
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen "\tw3\r\n"
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen "\n"
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen " body";
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenstatic void
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainentest_message_header_parser_one(struct message_header_parser_ctx *parser,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen enum message_header_parser_flags hdr_flags)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct message_header_line *hdr;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen bool use_full_value;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen use_full_value = hdr_flags != 0;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(message_parse_header_next(parser, &hdr) > 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->name_offset == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if ((hdr_flags & MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP) == 0)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->full_value_offset == 4);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen else
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen test_assert(hdr->full_value_offset == 5);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen test_assert(hdr->name_len == 2 && strcmp(hdr->name, "h1") == 0);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen if ((hdr_flags & MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP) == 0) {
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen test_assert(hdr->middle_len == 2 && memcmp(hdr->middle, ": ", 2) == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->value_len == 3 && memcmp(hdr->value, " v1", 3) == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen } else {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_assert(hdr->middle_len == 3 && memcmp(hdr->middle, ": ", 3) == 0);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_assert(hdr->value_len == 2 && memcmp(hdr->value, "v1", 2) == 0);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(!hdr->continues && !hdr->continued && !hdr->eoh &&
939a0d82523538b2de38a02bc9f790a67b7ebf47Timo Sirainen !hdr->no_newline && !hdr->crlf_newline);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(message_parse_header_next(parser, &hdr) > 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->name_offset == 8 && hdr->full_value_offset == 11);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->name_len == 2 && strcmp(hdr->name, "h2") == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->middle_len == 1 && memcmp(hdr->middle, ":", 1) == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->value_len == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->continues && !hdr->continued && !hdr->eoh &&
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen !hdr->no_newline && !hdr->crlf_newline);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (use_full_value) hdr->use_full_value = TRUE;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(message_parse_header_next(parser, &hdr) > 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->name_offset == 8 && hdr->full_value_offset == 11);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->name_len == 2 && strcmp(hdr->name, "h2") == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->middle_len == 1 && memcmp(hdr->middle, ":", 1) == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->value_len == 3 && memcmp(hdr->value, " v2", 3) == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(!hdr->continues && hdr->continued && !hdr->eoh &&
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen !hdr->no_newline && hdr->crlf_newline);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if ((hdr_flags & MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE) != 0) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->full_value_len == 3 &&
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen memcmp(hdr->full_value, " v2", 3) == 0);
3b49aee9ced3b0370a3be396aca53acd5f21418cTimo Sirainen } else if (use_full_value) {
3b49aee9ced3b0370a3be396aca53acd5f21418cTimo Sirainen test_assert(hdr->full_value_len == 4 &&
3b49aee9ced3b0370a3be396aca53acd5f21418cTimo Sirainen memcmp(hdr->full_value, "\n v2", 4) == 0);
3b49aee9ced3b0370a3be396aca53acd5f21418cTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(message_parse_header_next(parser, &hdr) > 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->name_offset == 17 && hdr->full_value_offset == 21);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->name_len == 2 && strcmp(hdr->name, "h3") == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->middle_len == 2 && memcmp(hdr->middle, ": ", 2) == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->value_len == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->continues && !hdr->continued && !hdr->eoh &&
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen !hdr->no_newline && hdr->crlf_newline);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen if (use_full_value) hdr->use_full_value = TRUE;
84ed9f8f3d0e5ed47607ef417618e49e4f865557Timo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(message_parse_header_next(parser, &hdr) > 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->name_offset == 17 && hdr->full_value_offset == 21);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->name_len == 2 && strcmp(hdr->name, "h3") == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->middle_len == 2 && memcmp(hdr->middle, ": ", 2) == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->value_len == 3 && memcmp(hdr->value, "\tv3", 3) == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->continues && hdr->continued && !hdr->eoh &&
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen !hdr->no_newline && !hdr->crlf_newline);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (use_full_value) hdr->use_full_value = TRUE;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if ((hdr_flags & MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE) != 0) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->full_value_len == 3 &&
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen memcmp(hdr->full_value, " v3", 3) == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen } else if ((hdr_flags & MESSAGE_HEADER_PARSER_FLAG_DROP_CR) != 0) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->full_value_len == 4 &&
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen memcmp(hdr->full_value, "\n\tv3", 4) == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen } else if (use_full_value) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->full_value_len == 5 &&
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen memcmp(hdr->full_value, "\r\n\tv3", 5) == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen test_assert(message_parse_header_next(parser, &hdr) > 0);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen test_assert(hdr->name_offset == 17 && hdr->full_value_offset == 21);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->name_len == 2 && strcmp(hdr->name, "h3") == 0);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen test_assert(hdr->middle_len == 2 && memcmp(hdr->middle, ": ", 2) == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->value_len == 3 && memcmp(hdr->value, "\tw3", 3) == 0);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen test_assert(!hdr->continues && hdr->continued && !hdr->eoh &&
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen !hdr->no_newline && hdr->crlf_newline);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen if ((hdr_flags & MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE) != 0) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->full_value_len == 6 &&
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen memcmp(hdr->full_value, " v3 w3", 6) == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen } else if ((hdr_flags & MESSAGE_HEADER_PARSER_FLAG_DROP_CR) != 0) {
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen test_assert(hdr->full_value_len == 8 &&
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen memcmp(hdr->full_value, "\n\tv3\n\tw3", 8) == 0);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen } else if (use_full_value) {
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen test_assert(hdr->full_value_len == 9 &&
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen memcmp(hdr->full_value, "\r\n\tv3\n\tw3", 9) == 0);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen }
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen test_assert(message_parse_header_next(parser, &hdr) > 0);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen test_assert(hdr->name_offset == 32 && hdr->full_value_offset == 32);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(hdr->name_len == 0 && hdr->middle_len == 0 && hdr->value_len == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(!hdr->continues && !hdr->continued && hdr->eoh &&
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen !hdr->no_newline && !hdr->crlf_newline);
c9dea5c23355dea35c6fa423de69f6507852efe4Timo Sirainen
c9dea5c23355dea35c6fa423de69f6507852efe4Timo Sirainen test_assert(message_parse_header_next(parser, &hdr) < 0);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen}
7a24bdc1a5e2d5368c2569b4852192f2bdb5a31fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic void test_message_header_parser(void)
7a24bdc1a5e2d5368c2569b4852192f2bdb5a31fTimo Sirainen{
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen static enum message_header_parser_flags max_hdr_flags =
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP |
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen MESSAGE_HEADER_PARSER_FLAG_DROP_CR |
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE;
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen enum message_header_parser_flags hdr_flags;
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen struct message_header_parser_ctx *parser;
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen struct message_size hdr_size;
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen struct istream *input;
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen test_begin("message header parser");
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen input = test_istream_create(test1_msg);
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen for (hdr_flags = 0; hdr_flags <= max_hdr_flags; hdr_flags++) {
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen i_stream_seek(input, 0);
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen parser = message_parse_header_init(input, &hdr_size, hdr_flags);
d22301419109ed4a38351715e6760011421dadecTimo Sirainen test_message_header_parser_one(parser, hdr_flags);
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen message_parse_header_deinit(&parser);
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen }
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen test_assert(hdr_size.physical_size == strlen(test1_msg)-TEST1_MSG_BODY_LEN);
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen test_assert(hdr_size.virtual_size == strlen(test1_msg) - TEST1_MSG_BODY_LEN + 4);
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen i_stream_unref(&input);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_end();
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic void hdr_write(string_t *str, struct message_header_line *hdr)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen{
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (!hdr->continued) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen str_append(str, hdr->name);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (hdr->middle_len > 0)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen str_append_n(str, hdr->middle, hdr->middle_len);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen }
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen str_append_n(str, hdr->value, hdr->value_len);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (!hdr->no_newline) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (hdr->crlf_newline)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen str_append_c(str, '\r');
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen str_append_c(str, '\n');
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen }
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic void test_message_header_parser_partial(void)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen{
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct message_header_parser_ctx *parser;
6d6c1517ef20e340a3aace406724fc8916f2d13fTimo Sirainen struct message_header_line *hdr;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct istream *input;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen unsigned int i, max = (strlen(test1_msg)-TEST1_MSG_BODY_LEN)*2;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen string_t *str;
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainen int ret;
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_begin("message header parser partial");
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen input = test_istream_create(test1_msg);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_istream_set_allow_eof(input, FALSE);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen str = t_str_new(max);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen parser = message_parse_header_init(input, NULL, 0);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen for (i = 0; i <= max; i++) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_istream_set_size(input, i/2);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen while ((ret = message_parse_header_next(parser, &hdr)) > 0)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen hdr_write(str, hdr);
939a0d82523538b2de38a02bc9f790a67b7ebf47Timo Sirainen test_assert((ret == 0 && i < max) ||
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen (ret < 0 && i == max));
939a0d82523538b2de38a02bc9f790a67b7ebf47Timo Sirainen }
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen message_parse_header_deinit(&parser);
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen str_append(str, " body");
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_assert(strcmp(str_c(str), test1_msg) == 0);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen i_stream_unref(&input);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_end();
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic void
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainentest_message_header_parser_long_lines_str(const char *str,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen unsigned int buffer_size,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct message_size *size_r)
939a0d82523538b2de38a02bc9f790a67b7ebf47Timo Sirainen{
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen struct message_header_parser_ctx *parser;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct message_header_line *hdr;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct istream *input;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen unsigned int i;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen size_t len = strlen(str);
939a0d82523538b2de38a02bc9f790a67b7ebf47Timo Sirainen
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen input = test_istream_create(str);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_istream_set_max_buffer_size(input, buffer_size);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen parser = message_parse_header_init(input, size_r, 0);
939a0d82523538b2de38a02bc9f790a67b7ebf47Timo Sirainen for (i = 1; i <= len; i++) {
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen test_istream_set_size(input, i);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen while (message_parse_header_next(parser, &hdr) > 0) ;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen }
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen message_parse_header_deinit(&parser);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen i_stream_unref(&input);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic void test_message_header_parser_long_lines(void)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen{
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen static const char *lf_str = "1234567890: 345\n\n";
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen static const char *crlf_str = "1234567890: 345\r\n\r\n";
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct message_size hdr_size;
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen size_t i, len;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen test_begin("message header parser long lines");
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen len = strlen(lf_str);
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen for (i = 2; i < len; i++) {
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen test_message_header_parser_long_lines_str(lf_str, i, &hdr_size);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_assert(hdr_size.physical_size == len);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_assert(hdr_size.virtual_size == len + 2);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen }
6d6c1517ef20e340a3aace406724fc8916f2d13fTimo Sirainen len = strlen(crlf_str);
6d6c1517ef20e340a3aace406724fc8916f2d13fTimo Sirainen for (i = 3; i < len; i++) {
6d6c1517ef20e340a3aace406724fc8916f2d13fTimo Sirainen test_message_header_parser_long_lines_str(crlf_str, i, &hdr_size);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_assert(hdr_size.physical_size == len);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_assert(hdr_size.virtual_size == len);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen }
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_end();
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
939a0d82523538b2de38a02bc9f790a67b7ebf47Timo Sirainenstatic void test_message_header_parser_extra_cr_in_eoh(void)
939a0d82523538b2de38a02bc9f790a67b7ebf47Timo Sirainen{
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen static const char *str = "a:b\n\r\r\n";
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct message_header_parser_ctx *parser;
939a0d82523538b2de38a02bc9f790a67b7ebf47Timo Sirainen struct message_header_line *hdr;
939a0d82523538b2de38a02bc9f790a67b7ebf47Timo Sirainen struct istream *input;
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_begin("message header parser extra CR in EOH");
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen input = test_istream_create(str);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen parser = message_parse_header_init(input, NULL, 0);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_assert(message_parse_header_next(parser, &hdr) > 0 &&
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen strcmp(hdr->name, "a") == 0);
4cf5f0934a25f1fd58f2780108f9d6498c455a1fTimo Sirainen test_assert(message_parse_header_next(parser, &hdr) > 0 &&
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen strcmp(hdr->name, "\r") == 0 && hdr->middle_len == 0 &&
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen hdr->value_len == 0 && !hdr->eoh);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_assert(message_parse_header_next(parser, &hdr) < 0);
c9dea5c23355dea35c6fa423de69f6507852efe4Timo Sirainen message_parse_header_deinit(&parser);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_assert(input->stream_errno == 0);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen i_stream_unref(&input);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_end();
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic void test_message_header_parser_no_eoh(void)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen{
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen static const char *str = "a:b\n";
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct message_header_parser_ctx *parser;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct message_header_line *hdr;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct istream *input;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_begin("message header parser no EOH");
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen input = test_istream_create(str);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen parser = message_parse_header_init(input, NULL, 0);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_assert(message_parse_header_next(parser, &hdr) > 0 &&
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen strcmp(hdr->name, "a") == 0);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_assert(message_parse_header_next(parser, &hdr) < 0);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen message_parse_header_deinit(&parser);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_assert(input->stream_errno == 0);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen i_stream_unref(&input);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_end();
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenint main(void)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen{
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen static void (*test_functions[])(void) = {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_message_header_parser,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_message_header_parser_partial,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_message_header_parser_long_lines,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_message_header_parser_extra_cr_in_eoh,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen test_message_header_parser_no_eoh,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen NULL
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen };
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen return test_run(test_functions);
6d6c1517ef20e340a3aace406724fc8916f2d13fTimo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen