test-message-header-parser.c revision 4b994089fc7e6f7f42f1d7932e893c2b13ed1451
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen/* Copyright (c) 2007-2015 Dovecot authors, see the included COPYING file */
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen#include "lib.h"
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen#include "str.h"
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen#include "istream.h"
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen#include "message-size.h"
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen#include "message-header-parser.h"
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen#include "test-common.h"
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen#define TEST1_MSG_BODY_LEN 5
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainenstatic const char *test1_msg =
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen "h1: v1\n"
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen "h2:\n"
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen " v2\r\n"
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen "h3: \r\n"
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen "\tv3\n"
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen "\tw3\r\n"
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen "\n"
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen " body";
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstatic void
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainentest_message_header_parser_one(struct message_header_parser_ctx *parser,
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen enum message_header_parser_flags hdr_flags)
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen{
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen struct message_header_line *hdr;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen bool use_full_value;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen use_full_value = hdr_flags != 0;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(message_parse_header_next(parser, &hdr) > 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->name_offset == 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen if ((hdr_flags & MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP) == 0)
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->full_value_offset == 4);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen else
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->full_value_offset == 5);
bc3698b8892df8003b410daea6f5bbcd20433808Timo Sirainen test_assert(hdr->name_len == 2 && strcmp(hdr->name, "h1") == 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen if ((hdr_flags & MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP) == 0) {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->middle_len == 2 && memcmp(hdr->middle, ": ", 2) == 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->value_len == 3 && memcmp(hdr->value, " v1", 3) == 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen } else {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->middle_len == 3 && memcmp(hdr->middle, ": ", 3) == 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->value_len == 2 && memcmp(hdr->value, "v1", 2) == 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen }
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(!hdr->continues && !hdr->continued && !hdr->eoh &&
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen !hdr->no_newline && !hdr->crlf_newline);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(message_parse_header_next(parser, &hdr) > 0);
bc3698b8892df8003b410daea6f5bbcd20433808Timo Sirainen test_assert(hdr->name_offset == 8 && hdr->full_value_offset == 11);
bc3698b8892df8003b410daea6f5bbcd20433808Timo Sirainen test_assert(hdr->name_len == 2 && strcmp(hdr->name, "h2") == 0);
bc3698b8892df8003b410daea6f5bbcd20433808Timo Sirainen test_assert(hdr->middle_len == 1 && memcmp(hdr->middle, ":", 1) == 0);
bc3698b8892df8003b410daea6f5bbcd20433808Timo Sirainen test_assert(hdr->value_len == 0);
bc3698b8892df8003b410daea6f5bbcd20433808Timo Sirainen test_assert(hdr->continues && !hdr->continued && !hdr->eoh &&
bc3698b8892df8003b410daea6f5bbcd20433808Timo Sirainen !hdr->no_newline && !hdr->crlf_newline);
bc3698b8892df8003b410daea6f5bbcd20433808Timo Sirainen if (use_full_value) hdr->use_full_value = TRUE;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(message_parse_header_next(parser, &hdr) > 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->name_offset == 8 && hdr->full_value_offset == 11);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->name_len == 2 && strcmp(hdr->name, "h2") == 0);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen test_assert(hdr->middle_len == 1 && memcmp(hdr->middle, ":", 1) == 0);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen test_assert(hdr->value_len == 3 && memcmp(hdr->value, " v2", 3) == 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(!hdr->continues && hdr->continued && !hdr->eoh &&
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen !hdr->no_newline && hdr->crlf_newline);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen if ((hdr_flags & MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE) != 0) {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->full_value_len == 3 &&
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen memcmp(hdr->full_value, " v2", 3) == 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen } else if (use_full_value) {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->full_value_len == 4 &&
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen memcmp(hdr->full_value, "\n v2", 4) == 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen }
b2c1349cf07410aefab0f5b17153af9e5cfcf48fTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(message_parse_header_next(parser, &hdr) > 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->name_offset == 17 && hdr->full_value_offset == 21);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->name_len == 2 && strcmp(hdr->name, "h3") == 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->middle_len == 2 && memcmp(hdr->middle, ": ", 2) == 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->value_len == 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->continues && !hdr->continued && !hdr->eoh &&
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen !hdr->no_newline && hdr->crlf_newline);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen if (use_full_value) hdr->use_full_value = TRUE;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(message_parse_header_next(parser, &hdr) > 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->name_offset == 17 && hdr->full_value_offset == 21);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->name_len == 2 && strcmp(hdr->name, "h3") == 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->middle_len == 2 && memcmp(hdr->middle, ": ", 2) == 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->value_len == 3 && memcmp(hdr->value, "\tv3", 3) == 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->continues && hdr->continued && !hdr->eoh &&
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen !hdr->no_newline && !hdr->crlf_newline);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen if (use_full_value) hdr->use_full_value = TRUE;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen if ((hdr_flags & MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE) != 0) {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->full_value_len == 3 &&
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen memcmp(hdr->full_value, " v3", 3) == 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen } else if ((hdr_flags & MESSAGE_HEADER_PARSER_FLAG_DROP_CR) != 0) {
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen test_assert(hdr->full_value_len == 4 &&
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen memcmp(hdr->full_value, "\n\tv3", 4) == 0);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen } else if (use_full_value) {
68efcccb384f2d6871164b072457e87473502c51Timo Sirainen test_assert(hdr->full_value_len == 5 &&
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen memcmp(hdr->full_value, "\r\n\tv3", 5) == 0);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen }
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen test_assert(message_parse_header_next(parser, &hdr) > 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->name_offset == 17 && hdr->full_value_offset == 21);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->name_len == 2 && strcmp(hdr->name, "h3") == 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->middle_len == 2 && memcmp(hdr->middle, ": ", 2) == 0);
68efcccb384f2d6871164b072457e87473502c51Timo Sirainen test_assert(hdr->value_len == 3 && memcmp(hdr->value, "\tw3", 3) == 0);
68efcccb384f2d6871164b072457e87473502c51Timo Sirainen test_assert(!hdr->continues && hdr->continued && !hdr->eoh &&
68efcccb384f2d6871164b072457e87473502c51Timo Sirainen !hdr->no_newline && hdr->crlf_newline);
68efcccb384f2d6871164b072457e87473502c51Timo Sirainen if ((hdr_flags & MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE) != 0) {
68efcccb384f2d6871164b072457e87473502c51Timo Sirainen test_assert(hdr->full_value_len == 6 &&
68efcccb384f2d6871164b072457e87473502c51Timo Sirainen memcmp(hdr->full_value, " v3 w3", 6) == 0);
68efcccb384f2d6871164b072457e87473502c51Timo Sirainen } else if ((hdr_flags & MESSAGE_HEADER_PARSER_FLAG_DROP_CR) != 0) {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->full_value_len == 8 &&
68efcccb384f2d6871164b072457e87473502c51Timo Sirainen memcmp(hdr->full_value, "\n\tv3\n\tw3", 8) == 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen } else if (use_full_value) {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->full_value_len == 9 &&
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen memcmp(hdr->full_value, "\r\n\tv3\n\tw3", 9) == 0);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen }
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(message_parse_header_next(parser, &hdr) > 0);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->name_offset == 32 && hdr->full_value_offset == 32);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr->name_len == 0 && hdr->middle_len == 0 && hdr->value_len == 0);
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen test_assert(!hdr->continues && !hdr->continued && hdr->eoh &&
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen !hdr->no_newline && !hdr->crlf_newline);
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen test_assert(message_parse_header_next(parser, &hdr) < 0);
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstatic void test_message_header_parser(void)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen static enum message_header_parser_flags max_hdr_flags =
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP |
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen MESSAGE_HEADER_PARSER_FLAG_DROP_CR |
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE;
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen enum message_header_parser_flags hdr_flags;
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen struct message_header_parser_ctx *parser;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen struct message_size hdr_size;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen struct istream *input;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen test_begin("message header parser");
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen input = test_istream_create(test1_msg);
68efcccb384f2d6871164b072457e87473502c51Timo Sirainen
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen for (hdr_flags = 0; hdr_flags <= max_hdr_flags; hdr_flags++) {
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen i_stream_seek(input, 0);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen parser = message_parse_header_init(input, &hdr_size, hdr_flags);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_message_header_parser_one(parser, hdr_flags);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen message_parse_header_deinit(&parser);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen }
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr_size.physical_size == strlen(test1_msg)-TEST1_MSG_BODY_LEN);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_assert(hdr_size.virtual_size == strlen(test1_msg) - TEST1_MSG_BODY_LEN + 4);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen i_stream_unref(&input);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_end();
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen}
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainenstatic void hdr_write(string_t *str, struct message_header_line *hdr)
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen{
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen if (!hdr->continued) {
68efcccb384f2d6871164b072457e87473502c51Timo Sirainen str_append(str, hdr->name);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen str_append_n(str, hdr->middle, hdr->middle_len);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen }
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen str_append_n(str, hdr->value, hdr->value_len);
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen if (!hdr->no_newline) {
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen if (hdr->crlf_newline)
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen str_append_c(str, '\r');
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen str_append_c(str, '\n');
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen }
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen}
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainenstatic void test_message_header_parser_partial(void)
68efcccb384f2d6871164b072457e87473502c51Timo Sirainen{
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen struct message_header_parser_ctx *parser;
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen struct message_header_line *hdr;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen struct istream *input;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen unsigned int i, max = (strlen(test1_msg)-TEST1_MSG_BODY_LEN)*2;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen string_t *str;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen int ret;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_begin("message header parser partial");
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen input = test_istream_create(test1_msg);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_istream_set_allow_eof(input, FALSE);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen str = t_str_new(max);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen parser = message_parse_header_init(input, NULL, 0);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen for (i = 0; i <= max; i++) {
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen test_istream_set_size(input, i/2);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen while ((ret = message_parse_header_next(parser, &hdr)) > 0)
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen hdr_write(str, hdr);
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen test_assert((ret == 0 && i < max) ||
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen (ret < 0 && i == max));
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen }
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen message_parse_header_deinit(&parser);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen str_append(str, " body");
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen test_assert(strcmp(str_c(str), test1_msg) == 0);
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen i_stream_unref(&input);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen test_end();
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen}
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainenstatic void
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainentest_message_header_parser_long_lines_str(const char *str,
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen unsigned int buffer_size,
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen struct message_size *size_r)
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen{
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen struct message_header_parser_ctx *parser;
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen struct message_header_line *hdr;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen struct istream *input;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen unsigned int i, len = strlen(str);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen input = test_istream_create(str);
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen test_istream_set_max_buffer_size(input, buffer_size);
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen parser = message_parse_header_init(input, size_r, 0);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen for (i = 1; i <= len; i++) {
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen test_istream_set_size(input, i);
294f1a51763015cda0e2d874c5027d6fe7a2cd54Timo Sirainen while (message_parse_header_next(parser, &hdr) > 0) ;
18634dae6e304bac982bb1e0ff1b6b88fc448dbcTimo Sirainen }
18634dae6e304bac982bb1e0ff1b6b88fc448dbcTimo Sirainen message_parse_header_deinit(&parser);
18634dae6e304bac982bb1e0ff1b6b88fc448dbcTimo Sirainen i_stream_unref(&input);
18634dae6e304bac982bb1e0ff1b6b88fc448dbcTimo Sirainen}
18634dae6e304bac982bb1e0ff1b6b88fc448dbcTimo Sirainen
18634dae6e304bac982bb1e0ff1b6b88fc448dbcTimo Sirainenstatic void test_message_header_parser_long_lines(void)
18634dae6e304bac982bb1e0ff1b6b88fc448dbcTimo Sirainen{
18634dae6e304bac982bb1e0ff1b6b88fc448dbcTimo Sirainen static const char *lf_str = "1234567890: 345\n\n";
294f1a51763015cda0e2d874c5027d6fe7a2cd54Timo Sirainen static const char *crlf_str = "1234567890: 345\r\n\r\n";
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen struct message_size hdr_size;
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen unsigned int i, len;
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen test_begin("message header parser long lines");
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen len = strlen(lf_str);
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen for (i = 2; i < len; i++) {
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen test_message_header_parser_long_lines_str(lf_str, i, &hdr_size);
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen test_assert(hdr_size.physical_size == len);
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen test_assert(hdr_size.virtual_size == len + 2);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen }
len = strlen(crlf_str);
for (i = 3; 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();
}
static void test_message_header_parser_extra_cr_in_eoh(void)
{
static const char *str = "a:b\n\r\r\n";
struct message_header_parser_ctx *parser;
struct message_header_line *hdr;
struct istream *input;
test_begin("message header parser extra CR in EOH");
input = test_istream_create(str);
parser = message_parse_header_init(input, NULL, 0);
test_assert(message_parse_header_next(parser, &hdr) > 0 &&
strcmp(hdr->name, "a") == 0);
test_assert(message_parse_header_next(parser, &hdr) > 0 &&
strcmp(hdr->name, "\r") == 0 && hdr->middle_len == 0 &&
hdr->value_len == 0 && !hdr->eoh);
test_assert(message_parse_header_next(parser, &hdr) < 0);
message_parse_header_deinit(&parser);
test_assert(input->stream_errno == 0);
i_stream_unref(&input);
test_end();
}
static void test_message_header_parser_no_eoh(void)
{
static const char *str = "a:b\n";
struct message_header_parser_ctx *parser;
struct message_header_line *hdr;
struct istream *input;
test_begin("message header parser no EOH");
input = test_istream_create(str);
parser = message_parse_header_init(input, NULL, 0);
test_assert(message_parse_header_next(parser, &hdr) > 0 &&
strcmp(hdr->name, "a") == 0);
test_assert(message_parse_header_next(parser, &hdr) < 0);
message_parse_header_deinit(&parser);
test_assert(input->stream_errno == 0);
i_stream_unref(&input);
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,
test_message_header_parser_extra_cr_in_eoh,
test_message_header_parser_no_eoh,
NULL
};
return test_run(test_functions);
}