From: Stephan Bosch Date: Fri, 13 Sep 2019 00:04:59 +0000 (+0200) Subject: lib-smtp: smtp-address - Add SMTP_ADDRESS_PARSE_FLAG_PRESERVE_RAW parse flag. X-Git-Tag: 2.3.9~123 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f8995ce3fcf83ca28c86c9037d5903791f2f224f;p=thirdparty%2Fdovecot%2Fcore.git lib-smtp: smtp-address - Add SMTP_ADDRESS_PARSE_FLAG_PRESERVE_RAW parse flag. It stores the unparsed representation of the address in the new raw field of struct smtp_address. This is only relevant to smtp_address_parse_path(). --- diff --git a/src/lib-smtp/smtp-address.c b/src/lib-smtp/smtp-address.c index d0fde23410..ff5cead53a 100644 --- a/src/lib-smtp/smtp-address.c +++ b/src/lib-smtp/smtp-address.c @@ -378,6 +378,18 @@ int smtp_address_parse_path_full(pool_t pool, const char *path, return -1; } + if (HAS_ALL_BITS(flags, SMTP_ADDRESS_PARSE_FLAG_PRESERVE_RAW) && + aparser.address.localpart != NULL) { + if (aparser.path && + ((const unsigned char *)(path + 1) < aparser.parser.cur)) { + aparser.address.raw = t_strdup_until( + path + 1, aparser.parser.cur - 1); + } else { + aparser.address.raw = t_strdup_until( + path, aparser.parser.cur); + } + } + if (address_r != NULL) *address_r = smtp_address_clone(pool, &aparser.address); return 0; diff --git a/src/lib-smtp/smtp-address.h b/src/lib-smtp/smtp-address.h index 3663bd1348..d59d82822a 100644 --- a/src/lib-smtp/smtp-address.h +++ b/src/lib-smtp/smtp-address.h @@ -12,7 +12,8 @@ enum smtp_address_parse_flags { SMTP_ADDRESS_PARSE_FLAG_ALLOW_EMPTY = BIT(1), /* Allow an address without a domain part */ SMTP_ADDRESS_PARSE_FLAG_ALLOW_LOCALPART = BIT(2), - /* Allow omission of the <...> brackets in a path */ + /* Allow omission of the <...> brackets in a path. This flag is only + relevant for smtp_address_parse_path(). */ SMTP_ADDRESS_PARSE_FLAG_BRACKETS_OPTIONAL = BIT(3), /* Allow localpart to have all kinds of bad unquoted characters by parsing the last '@' in the string directly as the localpart/domain @@ -21,6 +22,10 @@ enum smtp_address_parse_flags { cannot be used to construct a valid RFC 5321 address. */ SMTP_ADDRESS_PARSE_FLAG_ALLOW_BAD_LOCALPART = BIT(4), + /* Store an unparsed copy of the address in the `raw' field of struct + smtp_address. This flag is only relevant for + smtp_address_parse_path(). */ + SMTP_ADDRESS_PARSE_FLAG_PRESERVE_RAW = BIT(5), }; struct smtp_address { diff --git a/src/lib-smtp/test-smtp-address.c b/src/lib-smtp/test-smtp-address.c index 1d07c5aefe..08ef9b3e2c 100644 --- a/src/lib-smtp/test-smtp-address.c +++ b/src/lib-smtp/test-smtp-address.c @@ -216,6 +216,42 @@ valid_path_parse_tests[] = { .address = { .localpart = "user", .domain = "domain.tld" }, .output = "" }, + /* Raw */ + { + .input = "<>", + .flags = SMTP_ADDRESS_PARSE_FLAG_ALLOW_EMPTY | + SMTP_ADDRESS_PARSE_FLAG_PRESERVE_RAW, + .address = { .localpart = NULL, .domain = NULL, .raw = NULL } + }, + { + .input = "", + .flags = SMTP_ADDRESS_PARSE_FLAG_ALLOW_LOCALPART | + SMTP_ADDRESS_PARSE_FLAG_PRESERVE_RAW, + .address = { .localpart = "user", .domain = NULL, + .raw = "user" } + }, + { + .input = "", + .flags = SMTP_ADDRESS_PARSE_FLAG_PRESERVE_RAW, + .address = { .localpart = "user", .domain = "domain.tld", + .raw = "user@domain.tld" } + }, + { + .input = "<@otherdomain.tld,@yetanotherdomain.tld:user@domain.tld>", + .flags = SMTP_ADDRESS_PARSE_FLAG_PRESERVE_RAW, + .address = { .localpart = "user", .domain = "domain.tld", + .raw = "@otherdomain.tld,@yetanotherdomain.tld:" + "user@domain.tld" }, + .output = "" + }, + { + .input = "user@domain.tld", + .flags = SMTP_ADDRESS_PARSE_FLAG_BRACKETS_OPTIONAL | + SMTP_ADDRESS_PARSE_FLAG_PRESERVE_RAW, + .address = { .localpart = "user", .domain = "domain.tld", + .raw = "user@domain.tld"}, + .output = "" + }, }; unsigned int valid_path_parse_test_count = @@ -244,6 +280,16 @@ test_smtp_path_equal(const struct smtp_address *test, parsed->domain), null_strcmp(parsed->domain, test->domain) == 0); } + if (parsed == NULL) { + /* nothing */ + } else if (parsed->raw == NULL) { + test_out_quiet(t_strdup_printf("address->raw = (null)"), + (parsed->raw == test->raw)); + } else { + test_out_quiet(t_strdup_printf("address->raw = \"%s\"", + parsed->raw), + null_strcmp(parsed->raw, test->raw) == 0); + } } static void test_smtp_path_parse_valid(void)