bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch#include "lib.h"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch#include "istream.h"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch#include "str.h"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch#include "message-part-data.h"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch#include "message-parser.h"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch#include "imap-envelope.h"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch#include "test-common.h"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschstruct parse_test {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch const char *message;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch const char *envelope;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch};
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschstruct parse_test parse_tests[] = {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch /* Tests copied from imaptest */
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch .message =
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "Message-ID: <msg@id>\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "In-Reply-To: <reply@to.id>\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "Date: Thu, 15 Feb 2007 01:02:03 +0200\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "Subject: subject header\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "From: From Real <fromuser@fromdomain.org>\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "To: To Real <touser@todomain.org>\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "Cc: Cc Real <ccuser@ccdomain.org>\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "Bcc: Bcc Real <bccuser@bccdomain.org>\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "Sender: Sender Real <senderuser@senderdomain.org>\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "Reply-To: ReplyTo Real <replytouser@replytodomain.org>\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "body\n",
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch .envelope =
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "\"Thu, 15 Feb 2007 01:02:03 +0200\" "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "\"subject header\" "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((\"From Real\" NIL \"fromuser\" \"fromdomain.org\")) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((\"Sender Real\" NIL \"senderuser\" \"senderdomain.org\")) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((\"ReplyTo Real\" NIL \"replytouser\" \"replytodomain.org\")) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((\"To Real\" NIL \"touser\" \"todomain.org\")) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((\"Cc Real\" NIL \"ccuser\" \"ccdomain.org\")) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((\"Bcc Real\" NIL \"bccuser\" \"bccdomain.org\")) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "\"<reply@to.id>\" \"<msg@id>\""
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch }, {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch .message =
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "Date: Thu, 15 Feb 2007 01:02:03 +0200\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "From: user@domain\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "body\n",
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch .envelope =
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "\"Thu, 15 Feb 2007 01:02:03 +0200\" NIL "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((NIL NIL \"user\" \"domain\")) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((NIL NIL \"user\" \"domain\")) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((NIL NIL \"user\" \"domain\")) NIL NIL NIL NIL NIL"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch }, {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch .message =
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "Date: Thu, 15 Feb 2007 01:02:03 +0200\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "From: user@domain\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "body\n",
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch .envelope =
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "\"Thu, 15 Feb 2007 01:02:03 +0200\" NIL "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((NIL NIL \"user\" \"domain\")) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((NIL NIL \"user\" \"domain\")) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((NIL NIL \"user\" \"domain\")) NIL NIL NIL NIL NIL"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch }, {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch .message =
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "Date: Thu, 15 Feb 2007 01:02:03 +0200\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "From: user@domain (Real Name)\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "To: group: g1@d1.org, g2@d2.org;, group2: g3@d3.org;\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "Cc: group:;, group2: (foo) ;\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "body\n",
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch .envelope =
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "\"Thu, 15 Feb 2007 01:02:03 +0200\" NIL "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((\"Real Name\" NIL \"user\" \"domain\")) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((\"Real Name\" NIL \"user\" \"domain\")) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((\"Real Name\" NIL \"user\" \"domain\")) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((NIL NIL \"group\" NIL)"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "(NIL NIL \"g1\" \"d1.org\")"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "(NIL NIL \"g2\" \"d2.org\")"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "(NIL NIL NIL NIL)"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "(NIL NIL \"group2\" NIL)"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "(NIL NIL \"g3\" \"d3.org\")"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "(NIL NIL NIL NIL)) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((NIL NIL \"group\" NIL)(NIL NIL NIL NIL)"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "(NIL NIL \"group2\" NIL)(NIL NIL NIL NIL)) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "NIL NIL NIL"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch }, {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch .message =
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "Date: Thu, 15 Feb 2007 01:02:03 +0200\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "From: user@domain (Real Name)\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "Sender: \n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "Reply-To: \n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "body\n",
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch .envelope =
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "\"Thu, 15 Feb 2007 01:02:03 +0200\" NIL "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((\"Real Name\" NIL \"user\" \"domain\")) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((\"Real Name\" NIL \"user\" \"domain\")) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((\"Real Name\" NIL \"user\" \"domain\")) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "NIL NIL NIL NIL NIL"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch }, {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch .message =
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "Date: Thu, 15 Feb 2007 01:02:03 +0200\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "From: <@route:user@domain>\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "\n"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "body\n",
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch .envelope =
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "\"Thu, 15 Feb 2007 01:02:03 +0200\" NIL "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((NIL \"@route\" \"user\" \"domain\")) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((NIL \"@route\" \"user\" \"domain\")) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "((NIL \"@route\" \"user\" \"domain\")) "
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch "NIL NIL NIL NIL NIL"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch }
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch};
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschstatic const unsigned int parse_tests_count = N_ELEMENTS(parse_tests);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschstatic struct message_part_envelope *
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschmsg_parse(pool_t pool, const char *message)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch{
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch struct message_parser_ctx *parser;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch struct message_part_envelope *envlp = NULL;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch struct istream *input;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch struct message_block block;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch struct message_part *parts;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch int ret;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch input = i_stream_create_from_data(message, strlen(message));
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch parser = message_parser_init(pool, input,
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP |
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch MESSAGE_HEADER_PARSER_FLAG_DROP_CR,
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch while ((ret = message_parser_parse_next_block(parser, &block)) > 0) {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch i_assert(block.part->parent == NULL);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch message_part_envelope_parse_from_header(pool, &envlp, block.hdr);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch }
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch test_assert(ret < 0);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch message_parser_deinit(&parser, &parts);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch i_stream_unref(&input);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch return envlp;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch}
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschstatic void test_imap_envelope_write(void)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch{
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch struct message_part_envelope *envlp;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch unsigned int i;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch for (i = 0; i < parse_tests_count; i++) T_BEGIN {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch struct parse_test *test = &parse_tests[i];
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch string_t *str = t_str_new(128);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch pool_t pool = pool_alloconly_create("imap envelope write", 1024);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch test_begin(t_strdup_printf("imap envelope write [%u]", i));
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch envlp = msg_parse(pool, test->message);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch imap_envelope_write(envlp, str);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch test_assert(strcmp(str_c(str), test->envelope) == 0);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch pool_unref(&pool);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch test_end();
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch } T_END;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch}
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschstatic void test_imap_envelope_parse(void)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch{
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch struct message_part_envelope *envlp;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch const char *error;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch unsigned int i;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch bool ret;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch for (i = 0; i < parse_tests_count; i++) T_BEGIN {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch struct parse_test *test = &parse_tests[i];
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch string_t *str = t_str_new(128);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch pool_t pool = pool_alloconly_create("imap envelope parse", 1024);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch test_begin(t_strdup_printf("imap envelope parser [%u]", i));
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch ret = imap_envelope_parse(test->envelope, pool, &envlp, &error);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch test_assert(ret);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch if (ret) {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch str_truncate(str, 0);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch imap_envelope_write(envlp, str);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch test_assert(strcmp(str_c(str), test->envelope) == 0);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch } else {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch i_error("Invalid envelope: %s", error);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch }
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch pool_unref(&pool);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch test_end();
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch } T_END;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch}
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschint main(void)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch{
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch static void (*const test_functions[])(void) = {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch test_imap_envelope_write,
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch test_imap_envelope_parse,
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch NULL
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch };
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch return test_run(test_functions);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch}