]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: smtp-address - Add SMTP_ADDRESS_PARSE_FLAG_PRESERVE_RAW parse flag.
authorStephan Bosch <stephan.bosch@open-xchange.com>
Fri, 13 Sep 2019 00:04:59 +0000 (02:04 +0200)
committerStephan Bosch <stephan.bosch@open-xchange.com>
Fri, 4 Oct 2019 11:59:35 +0000 (13:59 +0200)
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().

src/lib-smtp/smtp-address.c
src/lib-smtp/smtp-address.h
src/lib-smtp/test-smtp-address.c

index d0fde2341058a0abae811c49528c6c680f23620e..ff5cead53a9f21f10ac043795b73a6e91a023652 100644 (file)
@@ -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;
index 3663bd13483c43777a759ad95e67028de7ccde77..d59d82822ae7214f0ad43a758d4c68a6317272ad 100644 (file)
@@ -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 {
index 1d07c5aefe0881636227cc2286c3c4816a885363..08ef9b3e2cd1f0c5e3cafad0117f420b59c58d72 100644 (file)
@@ -216,6 +216,42 @@ valid_path_parse_tests[] = {
                .address = { .localpart = "user", .domain = "domain.tld" },
                .output = "<user@domain.tld>"
        },
+       /* Raw */
+       {
+               .input = "<>",
+               .flags = SMTP_ADDRESS_PARSE_FLAG_ALLOW_EMPTY |
+                        SMTP_ADDRESS_PARSE_FLAG_PRESERVE_RAW,
+               .address = { .localpart = NULL, .domain = NULL, .raw = NULL }
+       },
+       {
+               .input = "<user>",
+               .flags = SMTP_ADDRESS_PARSE_FLAG_ALLOW_LOCALPART |
+                        SMTP_ADDRESS_PARSE_FLAG_PRESERVE_RAW,
+               .address = { .localpart = "user", .domain = NULL,
+                            .raw = "user" }
+       },
+       {
+               .input = "<user@domain.tld>",
+               .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 = "<user@domain.tld>"
+       },
+       {
+               .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 = "<user@domain.tld>"
+       },
 };
 
 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)