aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2017-11-10 19:26:20 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2017-11-10 19:26:20 +0000
commit44b9961895e11117b8500ae0d070046670f998e6 (patch)
treea032fcc40896a56dced485a91dfc547eb99e037a
parent8b1cf85652664b562a70060fc30e62b90823daee (diff)
downloadrspamd-44b9961895e11117b8500ae0d070046670f998e6.tar.gz
rspamd-44b9961895e11117b8500ae0d070046670f998e6.zip
[Fix] Plug memory leak when setting email addresses from Lua
+ Optimize emails addr structure and API MFH: rspamd-1.6
-rw-r--r--src/libmime/email_addr.c39
-rw-r--r--src/libmime/email_addr.h21
-rw-r--r--src/libserver/milter.c4
-rw-r--r--src/libserver/task.c4
-rw-r--r--src/lua/lua_task.c61
-rw-r--r--test/lua/unit/smtp_addr.lua2
6 files changed, 66 insertions, 65 deletions
diff --git a/src/libmime/email_addr.c b/src/libmime/email_addr.c
index 9e69b68ec..08071afc8 100644
--- a/src/libmime/email_addr.c
+++ b/src/libmime/email_addr.c
@@ -21,20 +21,6 @@
#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)
{
const char *h, *end;
@@ -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);
diff --git a/src/libmime/email_addr.h b/src/libmime/email_addr.h
index b4f192ee7..8c9b54713 100644
--- a/src/libmime/email_addr.h
+++ b/src/libmime/email_addr.h
@@ -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_ */
diff --git a/src/libserver/milter.c b/src/libserver/milter.c
index 2cced96ec..b809b89b6 100644
--- a/src/libserver/milter.c
+++ b/src/libserver/milter.c
@@ -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;
}
diff --git a/src/libserver/task.c b/src/libserver/task.c
index f4fcd8fb1..5986b8567 100644
--- a/src/libserver/task.c
+++ b/src/libserver/task.c
@@ -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);
diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c
index 4172d60b7..85f5c9902 100644
--- a/src/lua/lua_task.c
+++ b/src/lua/lua_task.c
@@ -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 {
diff --git a/test/lua/unit/smtp_addr.lua b/test/lua/unit/smtp_addr.lua
index efac3a2af..4aa7ecd52 100644
--- a/test/lua/unit/smtp_addr.lua
+++ b/test/lua/unit/smtp_addr.lua
@@ -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()