bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen#include "lib.h"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen#include "str.h"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen#include "message-address.h"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen#include "test-common.h"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainenstatic bool cmp_addr(const struct message_address *a1,
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen const struct message_address *a2)
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen{
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen return null_strcmp(a1->name, a2->name) == 0 &&
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen null_strcmp(a1->route, a2->route) == 0 &&
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen null_strcmp(a1->mailbox, a2->mailbox) == 0 &&
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen null_strcmp(a1->domain, a2->domain) == 0 &&
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen a1->invalid_syntax == a2->invalid_syntax;
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen}
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
e106213aebb4170904697814c168548e1ba97de9Timo Sirainenstatic const struct message_address *
e106213aebb4170904697814c168548e1ba97de9Timo Sirainentest_parse_address(const char *input, bool fill_missing)
4c9294fcb17fb12326ff5db29e2f882cf4bd7fedTimo Sirainen{
4c9294fcb17fb12326ff5db29e2f882cf4bd7fedTimo Sirainen /* duplicate the input (without trailing NUL) so valgrind notices
4c9294fcb17fb12326ff5db29e2f882cf4bd7fedTimo Sirainen if there's any out-of-bounds access */
4c9294fcb17fb12326ff5db29e2f882cf4bd7fedTimo Sirainen size_t input_len = strlen(input);
4c9294fcb17fb12326ff5db29e2f882cf4bd7fedTimo Sirainen unsigned char *input_dup = i_malloc(input_len);
4c9294fcb17fb12326ff5db29e2f882cf4bd7fedTimo Sirainen memcpy(input_dup, input, input_len);
4c9294fcb17fb12326ff5db29e2f882cf4bd7fedTimo Sirainen const struct message_address *addr =
4c9294fcb17fb12326ff5db29e2f882cf4bd7fedTimo Sirainen message_address_parse(pool_datastack_create(),
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen input_dup, input_len, UINT_MAX, fill_missing);
4c9294fcb17fb12326ff5db29e2f882cf4bd7fedTimo Sirainen i_free(input_dup);
4c9294fcb17fb12326ff5db29e2f882cf4bd7fedTimo Sirainen return addr;
4c9294fcb17fb12326ff5db29e2f882cf4bd7fedTimo Sirainen}
4c9294fcb17fb12326ff5db29e2f882cf4bd7fedTimo Sirainen
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainenstatic void test_message_address(void)
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen{
18a2214eedb08d043277cf1d3e75c45762014663Timo Sirainen static const struct test {
18a2214eedb08d043277cf1d3e75c45762014663Timo Sirainen const char *input;
18a2214eedb08d043277cf1d3e75c45762014663Timo Sirainen const char *wanted_output;
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen const char *wanted_filled_output;
18a2214eedb08d043277cf1d3e75c45762014663Timo Sirainen struct message_address addr;
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen struct message_address filled_addr;
18a2214eedb08d043277cf1d3e75c45762014663Timo Sirainen } tests[] = {
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen /* user@domain -> <user@domain> */
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "user@domain", "<user@domain>", NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "user", "domain", FALSE },
18a2214eedb08d043277cf1d3e75c45762014663Timo Sirainen { NULL, NULL, NULL, "user", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "\"user\"@domain", "<user@domain>", NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "user", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, NULL, NULL, "user", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "\"user name\"@domain", "<\"user name\"@domain>", NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "user name", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, NULL, NULL, "user name", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "\"user@na\\\\me\"@domain", "<\"user@na\\\\me\"@domain>", NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "user@na\\me", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, NULL, NULL, "user@na\\me", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "\"user\\\"name\"@domain", "<\"user\\\"name\"@domain>", NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "user\"name", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, NULL, NULL, "user\"name", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "\"\"@domain", "<\"\"@domain>", NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, NULL, NULL, "", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "user", "<user>", "<user@MISSING_DOMAIN>",
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "user", "", TRUE },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "user", "MISSING_DOMAIN", TRUE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "@domain", "<\"\"@domain>", "<MISSING_MAILBOX@domain>",
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "", "domain", TRUE },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "MISSING_MAILBOX", "domain", TRUE } },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen
5430411539347357344f6bf2552731b62f0a14fdTimo Sirainen /* Display Name -> Display Name */
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "Display Name", "\"Display Name\"", "\"Display Name\" <MISSING_MAILBOX@MISSING_DOMAIN>",
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", NULL, "", "", TRUE },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", NULL, "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "\"Display Name\"", "\"Display Name\"", "\"Display Name\" <MISSING_MAILBOX@MISSING_DOMAIN>",
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", NULL, "", "", TRUE },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", NULL, "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "Display \"Name\"", "\"Display Name\"", "\"Display Name\" <MISSING_MAILBOX@MISSING_DOMAIN>",
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", NULL, "", "", TRUE },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", NULL, "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "\"Display\" \"Name\"", "\"Display Name\"", "\"Display Name\" <MISSING_MAILBOX@MISSING_DOMAIN>",
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", NULL, "", "", TRUE },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", NULL, "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "\"\"", "", "<MISSING_MAILBOX@MISSING_DOMAIN>",
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "", NULL, "", "", TRUE },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "", NULL, "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE } },
5430411539347357344f6bf2552731b62f0a14fdTimo Sirainen
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen /* <user@domain> -> <user@domain> */
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "<user@domain>", NULL, NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "user", "domain", FALSE },
18a2214eedb08d043277cf1d3e75c45762014663Timo Sirainen { NULL, NULL, NULL, "user", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "<\"user\"@domain>", "<user@domain>", NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "user", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, NULL, NULL, "user", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "<\"user name\"@domain>", NULL, NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "user name", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, NULL, NULL, "user name", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "<\"user@na\\\\me\"@domain>", NULL, NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "user@na\\me", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, NULL, NULL, "user@na\\me", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "<\"user\\\"name\"@domain>", NULL, NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "user\"name", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, NULL, NULL, "user\"name", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "<\"\"@domain>", NULL, NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, NULL, NULL, "", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "<user>", NULL, "<user@MISSING_DOMAIN>",
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "user", "", TRUE },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "user", "MISSING_DOMAIN", TRUE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "<@route>", "<@route:\"\">", "<INVALID_ROUTE:MISSING_MAILBOX@MISSING_DOMAIN>",
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, "@route", "", "", TRUE },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, "INVALID_ROUTE", "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE } },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen /* user@domain (Display Name) -> "Display Name" <user@domain> */
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "user@domain (DisplayName)", "DisplayName <user@domain>", NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "DisplayName", NULL, "user", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, "DisplayName", NULL, "user", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "user@domain (Display Name)", "\"Display Name\" <user@domain>", NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", NULL, "user", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, "Display Name", NULL, "user", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "user@domain (Display\"Name)", "\"Display\\\"Name\" <user@domain>", NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display\"Name", NULL, "user", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, "Display\"Name", NULL, "user", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "user (Display Name)", "\"Display Name\" <user>", "\"Display Name\" <user@MISSING_DOMAIN>",
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", NULL, "user", "", TRUE },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", NULL, "user", "MISSING_DOMAIN", TRUE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "@domain (Display Name)", "\"Display Name\" <\"\"@domain>", "\"Display Name\" <MISSING_MAILBOX@domain>",
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", NULL, "", "domain", TRUE },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", NULL, "MISSING_MAILBOX", "domain", TRUE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "user@domain ()", "<user@domain>", NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "user", "domain", FALSE },
5430411539347357344f6bf2552731b62f0a14fdTimo Sirainen { NULL, NULL, NULL, "user", "domain", FALSE } },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen /* Display Name <user@domain> -> "Display Name" <user@domain> */
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "DisplayName <user@domain>", NULL, NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "DisplayName", NULL, "user", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, "DisplayName", NULL, "user", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "Display Name <user@domain>", "\"Display Name\" <user@domain>", NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", NULL, "user", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, "Display Name", NULL, "user", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "\"Display Name\" <user@domain>", NULL, NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", NULL, "user", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, "Display Name", NULL, "user", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "\"Display\\\"Name\" <user@domain>", NULL, NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display\"Name", NULL, "user", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, "Display\"Name", NULL, "user", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "Display Name <user>", "\"Display Name\" <user>", "\"Display Name\" <user@MISSING_DOMAIN>",
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", NULL, "user", "", TRUE },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", NULL, "user", "MISSING_DOMAIN", TRUE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "\"\" <user@domain>", "<user@domain>", NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "user", "domain", FALSE },
5430411539347357344f6bf2552731b62f0a14fdTimo Sirainen { NULL, NULL, NULL, "user", "domain", FALSE } },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen /* <@route:user@domain> -> <@route:user@domain> */
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "<@route:user@domain>", NULL, NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, "@route", "user", "domain", FALSE },
18a2214eedb08d043277cf1d3e75c45762014663Timo Sirainen { NULL, NULL, "@route", "user", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "<@route,@route2:user@domain>", NULL, NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, "@route,@route2", "user", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, NULL, "@route,@route2", "user", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "<@route@route2:user@domain>", "<@route,@route2:user@domain>", NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, "@route,@route2", "user", "domain", FALSE },
18a2214eedb08d043277cf1d3e75c45762014663Timo Sirainen { NULL, NULL, "@route,@route2", "user", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "<@route@route2:user>", "<@route,@route2:user>", "<@route,@route2:user@MISSING_DOMAIN>",
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, "@route,@route2", "user", "", TRUE },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, "@route,@route2", "user", "MISSING_DOMAIN", TRUE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "<@route@route2:\"\"@domain>", "<@route,@route2:\"\"@domain>", NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, "@route,@route2", "", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, NULL, "@route,@route2", "", "domain", FALSE } },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen /* Display Name <@route:user@domain> ->
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen "Display Name" <@route:user@domain> */
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "Display Name <@route:user@domain>", "\"Display Name\" <@route:user@domain>", NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", "@route", "user", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, "Display Name", "@route", "user", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "Display Name <@route,@route2:user@domain>", "\"Display Name\" <@route,@route2:user@domain>", NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", "@route,@route2", "user", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, "Display Name", "@route,@route2", "user", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "Display Name <@route@route2:user@domain>", "\"Display Name\" <@route,@route2:user@domain>", NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", "@route,@route2", "user", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, "Display Name", "@route,@route2", "user", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "Display Name <@route@route2:user>", "\"Display Name\" <@route,@route2:user>", "\"Display Name\" <@route,@route2:user@MISSING_DOMAIN>",
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", "@route,@route2", "user", "", TRUE },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", "@route,@route2", "user", "MISSING_DOMAIN", TRUE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "Display Name <@route@route2:\"\"@domain>", "\"Display Name\" <@route,@route2:\"\"@domain>", NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "Display Name", "@route,@route2", "", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, "Display Name", "@route,@route2", "", "domain", FALSE } },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen /* other tests: */
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "\"foo: <a@b>;,\" <user@domain>", NULL, NULL,
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, "foo: <a@b>;,", NULL, "user", "domain", FALSE },
6b8f4863bb2b0938d40f774122baf6528a833ea0Timo Sirainen { NULL, "foo: <a@b>;,", NULL, "user", "domain", FALSE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "<>", "", "<MISSING_MAILBOX@MISSING_DOMAIN>",
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "", "", TRUE },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE } },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { "<@>", "", "<INVALID_ROUTE:MISSING_MAILBOX@MISSING_DOMAIN>",
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, NULL, "", "", TRUE },
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen { NULL, NULL, "INVALID_ROUTE", "MISSING_MAILBOX", "MISSING_DOMAIN", TRUE } },
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen };
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen static struct message_address group_prefix = {
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen NULL, NULL, NULL, "group", NULL, FALSE
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen };
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen static struct message_address group_suffix = {
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen NULL, NULL, NULL, NULL, NULL, FALSE
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen };
4c9294fcb17fb12326ff5db29e2f882cf4bd7fedTimo Sirainen const struct message_address *addr;
a1973d0f171b027f9a7c642bc1c2134293731e1cTimo Sirainen string_t *str, *group;
a1973d0f171b027f9a7c642bc1c2134293731e1cTimo Sirainen const char *wanted_string;
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen unsigned int i;
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
a1973d0f171b027f9a7c642bc1c2134293731e1cTimo Sirainen test_begin("message address parsing");
a1973d0f171b027f9a7c642bc1c2134293731e1cTimo Sirainen str = t_str_new(128);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen group = t_str_new(256);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen for (i = 0; i < N_ELEMENTS(tests)*2; i++) {
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen const struct test *test = &tests[i/2];
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen const struct message_address *test_wanted_addr;
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen bool fill_missing = i%2 != 0;
18a2214eedb08d043277cf1d3e75c45762014663Timo Sirainen
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen test_wanted_addr = !fill_missing ?
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen &test->addr : &test->filled_addr;
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen addr = test_parse_address(test->input, fill_missing);
18a2214eedb08d043277cf1d3e75c45762014663Timo Sirainen test_assert_idx(addr != NULL && addr->next == NULL &&
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen cmp_addr(addr, test_wanted_addr), i);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen /* test the address alone */
a8ebb72c0fba1a6a71104e530bf5903d5f149351Timo Sirainen str_truncate(str, 0);
a8ebb72c0fba1a6a71104e530bf5903d5f149351Timo Sirainen message_address_write(str, addr);
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen if (fill_missing && test->wanted_filled_output != NULL)
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen wanted_string = test->wanted_filled_output;
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen else if (test->wanted_output != NULL)
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen wanted_string = test->wanted_output;
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen else
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen wanted_string = test->input;
a8ebb72c0fba1a6a71104e530bf5903d5f149351Timo Sirainen test_assert_idx(strcmp(str_c(str), wanted_string) == 0, i);
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen /* test the address as a list of itself */
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen for (unsigned int list_length = 2; list_length <= 5; list_length++) {
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen str_truncate(group, 0);
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen str_append(group, test->input);
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen for (unsigned int j = 1; j < list_length; j++) {
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen if ((j % 2) == 0)
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen str_append(group, ",");
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen else
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen str_append(group, " , \n ");
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen str_append(group, test->input);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen }
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen addr = test_parse_address(str_c(group), fill_missing);
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen for (unsigned int j = 0; j < list_length; j++) {
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen test_assert_idx(addr != NULL &&
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen cmp_addr(addr, test_wanted_addr), i);
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen if (addr != NULL)
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen addr = addr->next;
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen }
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen test_assert_idx(addr == NULL, i);
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen }
18a2214eedb08d043277cf1d3e75c45762014663Timo Sirainen
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen /* test the address as a group of itself */
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen for (unsigned int list_length = 1; list_length <= 5; list_length++) {
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen str_truncate(group, 0);
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen str_printfa(group, "group: %s", test->input);
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen for (unsigned int j = 1; j < list_length; j++) {
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen if ((j % 2) == 0)
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen str_append(group, ",");
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen else
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen str_append(group, " , \n ");
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen str_append(group, test->input);
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen }
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen str_append_c(group, ';');
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen addr = test_parse_address(str_c(group), fill_missing);
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen test_assert(addr != NULL && cmp_addr(addr, &group_prefix));
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen addr = addr->next;
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen for (unsigned int j = 0; j < list_length; j++) {
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen test_assert_idx(addr != NULL &&
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen cmp_addr(addr, test_wanted_addr), i);
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen if (addr != NULL)
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen addr = addr->next;
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen }
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen test_assert_idx(addr != NULL && addr->next == NULL &&
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen cmp_addr(addr, &group_suffix), i);
f55b07916c82db8b915b28252e44ce6fb2bd3080Timo Sirainen }
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen }
a1973d0f171b027f9a7c642bc1c2134293731e1cTimo Sirainen test_end();
a1973d0f171b027f9a7c642bc1c2134293731e1cTimo Sirainen
a1973d0f171b027f9a7c642bc1c2134293731e1cTimo Sirainen test_begin("message address parsing with empty group");
a1973d0f171b027f9a7c642bc1c2134293731e1cTimo Sirainen str_truncate(group, 0);
a1973d0f171b027f9a7c642bc1c2134293731e1cTimo Sirainen str_append(group, "group:;");
e106213aebb4170904697814c168548e1ba97de9Timo Sirainen addr = test_parse_address(str_c(group), FALSE);
99df8a838cd9c5257ea5a2554383a9a999191e38Pali Rohár str_truncate(str, 0);
99df8a838cd9c5257ea5a2554383a9a999191e38Pali Rohár message_address_write(str, addr);
a1973d0f171b027f9a7c642bc1c2134293731e1cTimo Sirainen test_assert(addr != NULL && cmp_addr(addr, &group_prefix));
a1973d0f171b027f9a7c642bc1c2134293731e1cTimo Sirainen addr = addr->next;
a1973d0f171b027f9a7c642bc1c2134293731e1cTimo Sirainen test_assert(addr != NULL && addr->next == NULL &&
a1973d0f171b027f9a7c642bc1c2134293731e1cTimo Sirainen cmp_addr(addr, &group_suffix));
99df8a838cd9c5257ea5a2554383a9a999191e38Pali Rohár test_assert(strcmp(str_c(str), "group:;") == 0);
a1973d0f171b027f9a7c642bc1c2134293731e1cTimo Sirainen test_end();
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen}
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
15581297511b658a29c707c6031a258bab7bf1a5Stephan Boschstatic int
15581297511b658a29c707c6031a258bab7bf1a5Stephan Boschtest_parse_path(const char *input, const struct message_address **addr_r)
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch{
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch struct message_address *addr;
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch int ret;
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch /* duplicate the input (without trailing NUL) so valgrind notices
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch if there's any out-of-bounds access */
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch size_t input_len = strlen(input);
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch unsigned char *input_dup = i_malloc(input_len);
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch memcpy(input_dup, input, input_len);
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch ret = message_address_parse_path(pool_datastack_create(),
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch input_dup, input_len, &addr);
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch i_free(input_dup);
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch *addr_r = addr;
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch return ret;
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch}
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch
15581297511b658a29c707c6031a258bab7bf1a5Stephan Boschstatic void test_message_address_path(void)
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch{
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch static const struct test {
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch const char *input;
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch const char *wanted_output;
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch struct message_address addr;
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch } tests[] = {
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch { "<>", NULL,
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch { NULL, NULL, NULL, NULL, NULL, FALSE } },
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch { " < > ", "<>",
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch { NULL, NULL, NULL, NULL, NULL, FALSE } },
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch { "<user@domain>", NULL,
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch { NULL, NULL, NULL, "user", "domain", FALSE } },
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch { " <user@domain> ", "<user@domain>",
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch { NULL, NULL, NULL, "user", "domain", FALSE } },
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch { "<\"user\"@domain>", "<user@domain>",
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch { NULL, NULL, NULL, "user", "domain", FALSE } },
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch { "<\"user name\"@domain>", NULL,
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch { NULL, NULL, NULL, "user name", "domain", FALSE } },
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch { "<\"user@na\\\\me\"@domain>", NULL,
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch { NULL, NULL, NULL, "user@na\\me", "domain", FALSE } },
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch { "<\"user\\\"name\"@domain>", NULL,
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch { NULL, NULL, NULL, "user\"name", "domain", FALSE } },
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch { "<\"\"@domain>", NULL,
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch { NULL, NULL, NULL, "", "domain", FALSE } },
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch };
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch const struct message_address *addr;
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch string_t *str;
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch const char *wanted_string;
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch unsigned int i;
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch test_begin("message address path parsing");
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch str = t_str_new(128);
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch for (i = 0; i < N_ELEMENTS(tests); i++) {
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch const struct test *test = &tests[i];
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch const struct message_address *test_wanted_addr;
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch int ret;
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch test_wanted_addr = &test->addr;
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch ret = test_parse_path(test->input, &addr);
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch test_assert_idx(ret == 0, i);
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch test_assert_idx(addr != NULL && addr->next == NULL &&
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch cmp_addr(addr, test_wanted_addr), i);
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch /* test the address alone */
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch str_truncate(str, 0);
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch message_address_write(str, addr);
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch if (test->wanted_output != NULL)
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch wanted_string = test->wanted_output;
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch else
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch wanted_string = test->input;
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch test_assert_idx(strcmp(str_c(str), wanted_string) == 0, i);
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch }
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch test_end();
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch}
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainenint main(void)
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen{
baf3e87e186453fda13bd21f7cbcb2efc8492e8bTimo Sirainen static void (*const test_functions[])(void) = {
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen test_message_address,
15581297511b658a29c707c6031a258bab7bf1a5Stephan Bosch test_message_address_path,
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen NULL
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen };
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen return test_run(test_functions);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen}