]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: address: Consistently allow address values to be NULL.
authorStephan Bosch <stephan.bosch@dovecot.fi>
Sat, 13 Jan 2018 10:51:24 +0000 (11:51 +0100)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Thu, 18 Jan 2018 07:10:12 +0000 (09:10 +0200)
If the address pointer is NULL or the localpart field is NULL or empty, it
signifies that it is the NULL address "<>".

In the case of smtp_address_equals(), this also likely fixes crashes at places
where it may be used to compare "<>".

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

index 53397b10ab998c1b6a35ff92e1bbf2114e52dc51..a277e22b7b1bcc85e261981d841bf2a8121be84a 100644 (file)
@@ -445,10 +445,13 @@ void smtp_address_detail_parse(pool_t pool, const char *delimiters,
        struct smtp_address *address, const char **username_r,
        char *delim_r, const char **detail_r)
 {
-       const char *localpart = address->localpart;
+       const char *localpart;
        const char *user, *p;
        size_t idx;
 
+       i_assert(!smtp_address_isnull(address));
+
+       localpart = address->localpart;
        user = localpart;
        *detail_r = "";
        *delim_r = '\0';
@@ -501,7 +504,7 @@ void smtp_address_write(string_t *out,
        const unsigned char *p, *pend, *pblock;
        size_t begin;
 
-       if (address == NULL || address->localpart == NULL)
+       if (smtp_address_isnull(address))
                return;
        begin = str_len(out);
 
@@ -603,17 +606,15 @@ smtp_address_clone(pool_t pool, const struct smtp_address *src)
        size_t size, lpsize, dsize;
        char *data, *localpart, *domain;
 
-       if (src == NULL)
+       if (smtp_address_isnull(src))
                return NULL;
 
        /* @UNSAFE */
 
        lpsize = dsize = 0;
        size = sizeof(struct smtp_address);
-       if (src->localpart != NULL) {
-               lpsize = strlen(src->localpart) + 1;
-               size = MALLOC_ADD(size, lpsize);
-       }
+       lpsize = strlen(src->localpart) + 1;
+       size = MALLOC_ADD(size, lpsize);
        if (src->domain != NULL) {
                dsize = strlen(src->domain) + 1;
                size = MALLOC_ADD(size, dsize);
@@ -661,6 +662,9 @@ smtp_address_clone_temp(const struct smtp_address *src)
 {
        struct smtp_address *new;
 
+       if (smtp_address_isnull(src))
+               return NULL;
+
        new = t_new(struct smtp_address, 1);
        new->localpart = t_strdup(src->localpart);
        new->domain = t_strdup(src->domain);
@@ -692,6 +696,8 @@ smtp_address_add_detail(pool_t pool, const struct smtp_address *address,
        struct smtp_address *new_addr;
        const char delim[] = {delim_c, '\0'};
 
+       i_assert(!smtp_address_isnull(address));
+
        new_addr = p_new(pool, struct smtp_address, 1);
        new_addr->localpart = p_strconcat(pool,
                address->localpart, delim, detail, NULL);
@@ -707,6 +713,8 @@ smtp_address_add_detail_temp(const struct smtp_address *address,
        struct smtp_address *new_addr;
        const char delim[] = {delim_c, '\0'};
 
+       i_assert(!smtp_address_isnull(address));
+
        new_addr = t_new(struct smtp_address, 1);
        new_addr->localpart = t_strconcat(
                address->localpart, delim, detail, NULL);
@@ -718,9 +726,16 @@ smtp_address_add_detail_temp(const struct smtp_address *address,
 int smtp_address_cmp(const struct smtp_address *address1,
        const struct smtp_address *address2)
 {
+       bool null1, null2;
        int ret;
 
-       if ((ret=strcasecmp(address1->localpart, address2->localpart)) != 0)
+       null1 = smtp_address_isnull(address1);
+       null2 = smtp_address_isnull(address2);
+       if (null1)
+               return (null2 ? 0 : -1);
+       else if (null2)
+               return 1;
+       if ((ret=null_strcasecmp(address1->domain, address2->domain)) != 0)
                return ret;
-       return strcasecmp(address1->domain, address2->domain);
+       return null_strcmp(address1->localpart, address2->localpart);
 }
index d68571846270a0014d4d5ed01439295344ba433d..a822b981d968b1a7ea45d341446dde52fc0fa080 100644 (file)
@@ -78,22 +78,26 @@ smtp_address_encode_path(const struct smtp_address *address)
  */
 
 void smtp_address_init(struct smtp_address *address,
-       const char *localpart, const char *domain);
+       const char *localpart, const char *domain) ATTR_NULL(2,3);
 void smtp_address_init_from_msg(struct smtp_address *address,
        const struct message_address *msg_addr);
 
 struct smtp_address *
-smtp_address_clone(pool_t pool, const struct smtp_address *address);
+smtp_address_clone(pool_t pool, const struct smtp_address *address)
+       ATTR_NULL(2);
 struct smtp_address *
-smtp_address_create(pool_t pool, const char *localpart, const char *domain);
+smtp_address_create(pool_t pool, const char *localpart, const char *domain)
+       ATTR_NULL(2, 3);
 struct smtp_address *
 smtp_address_create_from_msg(pool_t pool,
        const struct message_address *msg_addr);
 
 struct smtp_address *
-smtp_address_clone_temp(const struct smtp_address *address);
+smtp_address_clone_temp(const struct smtp_address *address)
+       ATTR_NULL(1);
 struct smtp_address *
-smtp_address_create_temp(const char *localpart, const char *domain);
+smtp_address_create_temp(const char *localpart, const char *domain)
+       ATTR_NULL(2, 3);
 struct smtp_address *
 smtp_address_create_from_msg_temp(const struct message_address *msg_addr);
 
@@ -105,9 +109,10 @@ smtp_address_add_detail_temp(const struct smtp_address *address,
        const char *detail, char delim_c);
 
 int smtp_address_cmp(const struct smtp_address *address1,
-       const struct smtp_address *address2);
+       const struct smtp_address *address2)
+       ATTR_NULL(1, 2);
 
-static inline bool
+static inline bool ATTR_NULL(1, 2)
 smtp_address_equals(const struct smtp_address *address1,
        const struct smtp_address *address2)
 {
index 3f1fd2b0f02573500d95a9d9d6c1eb0c27017312..6d937db991188f9cf0f4341babe765a6381172b6 100644 (file)
@@ -203,17 +203,19 @@ static void test_smtp_path_parse_valid(void)
                        test->input), ret > 0, error);
 
                if (ret > 0) {
-                       if (address->localpart == NULL ||
-                               test->address.localpart == NULL) {
-                               test_out(t_strdup_printf
-                                       ("address->localpart = %s", address->localpart),
-                                       (address->localpart == test->address.localpart));
+                       if (smtp_address_isnull(address) ||
+                               smtp_address_isnull(&test->address)) {
+                               test_out("address = <>",
+                                       smtp_address_isnull(address) &&
+                                       smtp_address_isnull(&test->address));
                        } else {
                                test_out(t_strdup_printf
                                        ("address->localpart = \"%s\"", address->localpart),
                                                strcmp(address->localpart, test->address.localpart) == 0);
                        }
-                       if (address->domain == NULL ||
+                       if (smtp_address_isnull(address)) {
+                               /* nothing */
+                       } else if (address->domain == NULL ||
                                test->address.domain == NULL) {
                                test_out(t_strdup_printf
                                        ("address->domain = %s", address->domain),
@@ -335,17 +337,19 @@ static void test_smtp_username_parse_valid(void)
                        test->input), ret > 0, error);
 
                if (ret > 0) {
-                       if (address->localpart == NULL ||
-                               test->address.localpart == NULL) {
-                               test_out(t_strdup_printf
-                                       ("address->localpart = %s", address->localpart),
-                                       (address->localpart == test->address.localpart));
+                       if (smtp_address_isnull(address) ||
+                               smtp_address_isnull(&test->address)) {
+                               test_out("address = <>",
+                                       smtp_address_isnull(address) &&
+                                       smtp_address_isnull(&test->address));
                        } else {
                                test_out(t_strdup_printf
                                        ("address->localpart = \"%s\"", address->localpart),
                                                strcmp(address->localpart, test->address.localpart) == 0);
                        }
-                       if (address->domain == NULL ||
+                       if (smtp_address_isnull(address)) {
+                               /* nothing */
+                       } else if (address->domain == NULL ||
                                test->address.domain == NULL) {
                                test_out(t_strdup_printf
                                        ("address->domain = %s", address->domain),