]> source.dussan.org Git - rspamd.git/commitdiff
[Fix] Plug memory leak when setting email addresses from Lua
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 10 Nov 2017 19:26:20 +0000 (19:26 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 10 Nov 2017 19:26:20 +0000 (19:26 +0000)
+ Optimize emails addr structure and API

MFH: rspamd-1.6

src/libmime/email_addr.c
src/libmime/email_addr.h
src/libserver/milter.c
src/libserver/task.c
src/lua/lua_task.c
test/lua/unit/smtp_addr.lua

index 9e69b68eceb2300ea520a1f9e5a4c22bf8159073..08071afc81045408580c2ed37b3463450ae375f6 100644 (file)
 #include "printf.h"
 #include "smtp_parsers.h"
 
-static void
-rspamd_email_addr_dtor (struct rspamd_email_address *addr)
-{
-       if (addr->flags & RSPAMD_EMAIL_ADDR_ADDR_ALLOCATED) {
-               g_free ((void *)addr->addr);
-       }
-
-       if (addr->flags & RSPAMD_EMAIL_ADDR_USER_ALLOCATED) {
-               g_free ((void *)addr->user);
-       }
-
-       g_free (addr);
-}
-
 static void
 rspamd_email_address_unescape (struct rspamd_email_address *addr)
 {
@@ -92,26 +78,24 @@ rspamd_email_address_from_smtp (const gchar *str, guint len)
                        ret->flags |= RSPAMD_EMAIL_ADDR_ADDR_ALLOCATED;
                }
 
-               REF_INIT_RETAIN (ret, rspamd_email_addr_dtor);
-
                return ret;
        }
 
        return NULL;
 }
 
-struct rspamd_email_address *
-rspamd_email_address_ref (struct rspamd_email_address *addr)
+void
+rspamd_email_address_free (struct rspamd_email_address *addr)
 {
-       REF_RETAIN (addr);
+       if (addr->flags & RSPAMD_EMAIL_ADDR_ADDR_ALLOCATED) {
+               g_free ((void *)addr->addr);
+       }
 
-       return addr;
-}
+       if (addr->flags & RSPAMD_EMAIL_ADDR_USER_ALLOCATED) {
+               g_free ((void *)addr->user);
+       }
 
-void
-rspamd_email_address_unref (struct rspamd_email_address *addr)
-{
-       REF_RELEASE (addr);
+       g_free (addr);
 }
 
 static inline void
@@ -152,11 +136,8 @@ rspamd_email_address_add (rspamd_mempool_t *pool,
                elt->flags |= RSPAMD_EMAIL_ADDR_ADDR_ALLOCATED;
        }
 
-       REF_INIT_RETAIN (elt, rspamd_email_addr_dtor);
-
        if (name->len > 0) {
                elt->name = rspamd_mime_header_decode (pool, name->str, name->len);
-               elt->name_len = strlen (elt->name);
        }
 
        g_ptr_array_add (ar, elt);
@@ -435,7 +416,7 @@ rspamd_email_address_list_destroy (gpointer ptr)
        struct rspamd_email_address *addr;
 
        PTR_ARRAY_FOREACH (ar, i, addr) {
-               REF_RELEASE (addr);
+               rspamd_email_address_free (addr);
        }
 
        g_ptr_array_free (ar, TRUE);
index b4f192ee7453d9cb9f9793fc2331d44fe84ccfa8..8c9b54713127f8ad4968a0432691719d7fb4a925 100644 (file)
@@ -28,11 +28,10 @@ enum rspamd_email_address_flags {
        RSPAMD_EMAIL_ADDR_BRACED = (1 << 2),
        RSPAMD_EMAIL_ADDR_QUOTED = (1 << 3),
        RSPAMD_EMAIL_ADDR_EMPTY = (1 << 4),
-       RSPAMD_EMAIL_ADDR_SMTP = (1 << 5),
-       RSPAMD_EMAIL_ADDR_HAS_BACKSLASH = (1 << 6),
-       RSPAMD_EMAIL_ADDR_ADDR_ALLOCATED = (1 << 7),
-       RSPAMD_EMAIL_ADDR_USER_ALLOCATED = (1 << 8),
-       RSPAMD_EMAIL_ADDR_HAS_8BIT = (1 << 9),
+       RSPAMD_EMAIL_ADDR_HAS_BACKSLASH = (1 << 5),
+       RSPAMD_EMAIL_ADDR_ADDR_ALLOCATED = (1 << 6),
+       RSPAMD_EMAIL_ADDR_USER_ALLOCATED = (1 << 7),
+       RSPAMD_EMAIL_ADDR_HAS_8BIT = (1 << 8),
 };
 
 /*
@@ -47,12 +46,9 @@ struct rspamd_email_address {
 
        guint raw_len;
        guint addr_len;
-       guint user_len;
        guint domain_len;
-       guint name_len;
-       enum rspamd_email_address_flags flags;
-
-       ref_entry_t ref;
+       guint16 user_len;
+       guchar flags;
 };
 
 /**
@@ -84,9 +80,6 @@ GPtrArray *rspamd_email_address_from_mime (rspamd_mempool_t *pool,
  */
 void rspamd_email_address_list_destroy (gpointer ptr);
 
-struct rspamd_email_address * rspamd_email_address_ref (
-               struct rspamd_email_address *addr);
-
-void rspamd_email_address_unref (struct rspamd_email_address *addr);
+void rspamd_email_address_free (struct rspamd_email_address *addr);
 
 #endif /* SRC_LIBMIME_EMAIL_ADDR_H_ */
index 2cced96eca897ff4d32623b0c828bc8c6de5cb5c..b809b89b62434d67953534ea1f35f0a6d9efc1c1 100644 (file)
@@ -117,7 +117,7 @@ rspamd_milter_session_reset (struct rspamd_milter_session *session,
 
                if (session->rcpts) {
                        PTR_ARRAY_FOREACH (session->rcpts, i, cur) {
-                               rspamd_email_address_unref (cur);
+                               rspamd_email_address_free (cur);
                        }
 
                        g_ptr_array_free (session->rcpts, TRUE);
@@ -125,7 +125,7 @@ rspamd_milter_session_reset (struct rspamd_milter_session *session,
                }
 
                if (session->from) {
-                       rspamd_email_address_unref (session->from);
+                       rspamd_email_address_free (session->from);
                        session->from = NULL;
                }
 
index f4fcd8fb10a4a25124ed490a80868a51778d3c80..5986b856742334b03296294f85ed4ab0324801bf 100644 (file)
@@ -241,14 +241,14 @@ rspamd_task_free (struct rspamd_task *task)
                if (task->rcpt_envelope) {
                        for (i = 0; i < task->rcpt_envelope->len; i ++) {
                                addr = g_ptr_array_index (task->rcpt_envelope, i);
-                               rspamd_email_address_unref (addr);
+                               rspamd_email_address_free (addr);
                        }
 
                        g_ptr_array_free (task->rcpt_envelope, TRUE);
                }
 
                if (task->from_envelope) {
-                       rspamd_email_address_unref (task->from_envelope);
+                       rspamd_email_address_free (task->from_envelope);
                }
 
                ucl_object_unref (task->messages);
index 4172d60b72bc1c9a959e7a435922cf9fcb50ac60..85f5c9902b83d66b3a92fcd1719763c73460c77f 100644 (file)
@@ -2170,9 +2170,9 @@ lua_push_email_address (lua_State *L, struct rspamd_email_address *addr)
                        lua_settable (L, -3);
                }
 
-               if (addr->name_len > 0) {
+               if (addr->name) {
                        lua_pushstring (L, "name");
-                       lua_pushlstring (L, addr->name, addr->name_len);
+                       lua_pushstring (L, addr->name);
                        lua_settable (L, -3);
                }
                else {
@@ -2218,6 +2218,7 @@ lua_import_email_address (lua_State *L, struct rspamd_task *task,
 {
        struct rspamd_email_address *addr;
        const gchar *p;
+       gchar *dst;
        gsize len;
 
        g_assert (paddr != NULL);
@@ -2226,16 +2227,16 @@ lua_import_email_address (lua_State *L, struct rspamd_task *task,
                return FALSE;
        }
 
-       addr = rspamd_mempool_alloc0 (task->task_pool, sizeof (*addr));
+       addr = g_malloc0 (sizeof (*addr));
 
        lua_pushstring (L, "name");
        lua_gettable (L, pos);
 
        if (lua_type (L, -1) == LUA_TSTRING) {
                p = lua_tolstring (L, -1, &len);
-               addr->name = (const gchar *)rspamd_mempool_alloc (task->task_pool, len);
-               memcpy ((gchar *)addr->name, p, len);
-               addr->name_len = len;
+               dst = rspamd_mempool_alloc (task->task_pool, len + 1);
+               rspamd_strlcpy (dst, p, len + 1);
+               addr->name = dst;
        }
 
        lua_pop (L, 1);
@@ -2295,19 +2296,26 @@ lua_import_email_address (lua_State *L, struct rspamd_task *task,
        }
        else {
                /* Construct raw addr */
-               len = addr->addr_len + addr->name_len + 3;
-               addr->raw = (const gchar *)rspamd_mempool_alloc (task->task_pool, len);
-               if (addr->name_len > 0) {
-                       addr->raw_len = rspamd_snprintf ((gchar *)addr->raw, len, "%*s <%*s>",
-                                       (int)addr->name_len, addr->name,
+               len = addr->addr_len + 3;
+
+               if (addr->name) {
+                       len += strlen (addr->name) + 1;
+                       dst = rspamd_mempool_alloc (task->task_pool, len + 1);
+
+                       addr->raw_len = rspamd_snprintf (dst, len, "%s <%*s>",
+                                       addr->name,
                                        (int)addr->addr_len, addr->addr);
 
                }
                else {
-                       addr->raw_len = rspamd_snprintf ((gchar *)addr->raw, len, "<%*s@%*s>",
-                                       (int)addr->name_len, addr->name,
-                                       (int)addr->addr_len, addr->addr);
+                       dst = rspamd_mempool_alloc (task->task_pool, len + 1);
+
+                       addr->raw_len = rspamd_snprintf (dst, len, "<%*s@%*s>",
+                                       (int)addr->user_len, addr->user,
+                                       (int)addr->domain_len, addr->domain);
                }
+
+               addr->raw = dst;
        }
 
        lua_pop (L, 1);
@@ -2401,13 +2409,19 @@ lua_task_set_recipients (lua_State *L)
                        break;
                }
                if (ptrs) {
-                       lua_pushvalue (L, pos);
+                       guint i;
+                       struct rspamd_email_address *tmp;
+
+                       PTR_ARRAY_FOREACH (ptrs, i, tmp) {
+                               rspamd_email_address_free (tmp);
+                       }
+
                        g_ptr_array_set_size (ptrs, 0);
+                       lua_pushvalue (L, pos);
 
                        for (lua_pushnil (L); lua_next (L, -2); lua_pop (L, 1)) {
                                if (lua_import_email_address (L, task, lua_gettop (L), &addr)) {
                                        g_ptr_array_add (ptrs, addr);
-                                       addr = NULL;
                                }
                        }
 
@@ -2624,6 +2638,13 @@ lua_task_set_from (lua_State *L)
 
                if (addrs) {
                        if (lua_import_email_address (L, task, pos, &addr)) {
+                               guint i;
+                               struct rspamd_email_address *tmp;
+
+                               PTR_ARRAY_FOREACH (addrs, i, tmp) {
+                                       rspamd_email_address_free (tmp);
+                               }
+
                                g_ptr_array_set_size (addrs, 0);
                                g_ptr_array_add (addrs, addr);
                                lua_pushboolean (L, true);
@@ -2633,7 +2654,13 @@ lua_task_set_from (lua_State *L)
                        }
                }
                else if (paddr) {
-                       if (lua_import_email_address (L, task, pos, paddr)) {
+                       if (lua_import_email_address (L, task, pos, &addr)) {
+
+                               if (paddr) {
+                                       rspamd_email_address_free (*paddr);
+                               }
+
+                               *paddr = addr;
                                lua_pushboolean (L, true);
                        }
                        else {
index efac3a2afef4f56a671ffa746e798b2de61b4a96..4aa7ecd523cf13350c34f4f78d21157dc391a4e1 100644 (file)
@@ -21,7 +21,7 @@ context("SMTP address check functions", function()
     int flags;
   };
   struct rspamd_email_address * rspamd_email_address_from_smtp (const char *str, unsigned len);
-  void rspamd_email_address_unref (struct rspamd_email_address *addr);
+  void rspamd_email_address_free (struct rspamd_email_address *addr);
   ]]
 
   test("Parse addrs", function()