From f8b94440fdc5cdde583832ab1daabd7ef84f3831 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 13 Aug 2019 11:24:04 +0100 Subject: [PATCH] [Rework] Use opaque structure to store a table of mime headers --- src/libmime/message.c | 4 +-- src/libmime/message.h | 4 +-- src/libmime/mime_headers.c | 54 ++++++++++++++++++++++++++++++-------- src/libmime/mime_headers.h | 13 ++++----- src/libmime/mime_parser.c | 2 +- 5 files changed, 55 insertions(+), 22 deletions(-) diff --git a/src/libmime/message.c b/src/libmime/message.c index 75e403e70..7eec503c9 100644 --- a/src/libmime/message.c +++ b/src/libmime/message.c @@ -1100,7 +1100,7 @@ rspamd_message_dtor (struct rspamd_message *msg) PTR_ARRAY_FOREACH (msg->parts, i, p) { if (p->raw_headers) { - rspamd_message_headers_destroy (p->raw_headers); + rspamd_message_headers_unref (p->raw_headers); } if (IS_CT_MULTIPART (p->ct)) { @@ -1122,7 +1122,7 @@ rspamd_message_dtor (struct rspamd_message *msg) } } - rspamd_message_headers_destroy (msg->raw_headers); + rspamd_message_headers_unref (msg->raw_headers); g_ptr_array_unref (msg->text_parts); g_ptr_array_unref (msg->parts); diff --git a/src/libmime/message.h b/src/libmime/message.h index a6b6f1022..651e1d457 100644 --- a/src/libmime/message.h +++ b/src/libmime/message.h @@ -62,7 +62,7 @@ struct rspamd_mime_part { struct rspamd_mime_part *parent_part; struct rspamd_mime_header *headers_order; - khash_t(rspamd_mime_headers_htb) *raw_headers; + struct rspamd_mime_headers_table *raw_headers; gchar *raw_headers_str; gsize raw_headers_len; @@ -148,7 +148,7 @@ struct rspamd_message { struct rspamd_received_header *received; /**< list of received headers */ GHashTable *urls; /**< list of parsed urls */ GHashTable *emails; /**< list of parsed emails */ - khash_t(rspamd_mime_headers_htb) *raw_headers; /**< list of raw headers */ + struct rspamd_mime_headers_table *raw_headers; /**< list of raw headers */ struct rspamd_mime_header *headers_order; /**< order of raw headers */ GPtrArray *rcpt_mime; GPtrArray *from_mime; diff --git a/src/libmime/mime_headers.c b/src/libmime/mime_headers.c index 7c6c02709..085dd3313 100644 --- a/src/libmime/mime_headers.c +++ b/src/libmime/mime_headers.c @@ -23,8 +23,14 @@ #include "libutil/util.h" #include -__KHASH_IMPL (rspamd_mime_headers_htb, static inline, gchar *, - struct rspamd_mime_header *, 1, rspamd_strcase_hash, rspamd_strcase_equal); +KHASH_INIT (rspamd_mime_headers_htb, gchar *, + struct rspamd_mime_header *, 1, + rspamd_strcase_hash, rspamd_strcase_equal); + +struct rspamd_mime_headers_table { + khash_t(rspamd_mime_headers_htb) htb; + ref_entry_t ref; +}; static void rspamd_mime_header_check_special (struct rspamd_task *task, @@ -177,7 +183,7 @@ rspamd_mime_header_add (struct rspamd_task *task, /* Convert raw headers to a list of struct raw_header * */ void rspamd_mime_headers_process (struct rspamd_task *task, - khash_t(rspamd_mime_headers_htb) *target, + struct rspamd_mime_headers_table *target, struct rspamd_mime_header **order_ptr, const gchar *in, gsize len, gboolean check_newlines) @@ -392,7 +398,7 @@ rspamd_mime_headers_process (struct rspamd_task *task, /* We also validate utf8 and replace all non-valid utf8 chars */ rspamd_mime_charset_utf_enforce (nh->decoded, strlen (nh->decoded)); nh->order = norder ++; - rspamd_mime_header_add (task, target, order_ptr, nh, check_newlines); + rspamd_mime_header_add (task, &target->htb, order_ptr, nh, check_newlines); nh = NULL; state = 0; break; @@ -402,7 +408,7 @@ rspamd_mime_headers_process (struct rspamd_task *task, nh->decoded = ""; nh->raw_len = p - nh->raw_value; nh->order = norder ++; - rspamd_mime_header_add (task, target, order_ptr, nh, check_newlines); + rspamd_mime_header_add (task, &target->htb, order_ptr, nh, check_newlines); nh = NULL; state = 0; break; @@ -1599,10 +1605,11 @@ rspamd_smtp_received_parse (struct rspamd_task *task, } struct rspamd_mime_header * -rspamd_message_get_header_from_hash (khash_t(rspamd_mime_headers_htb) *htb, +rspamd_message_get_header_from_hash (struct rspamd_mime_headers_table *headers, const gchar *field) { khiter_t k; + khash_t(rspamd_mime_headers_htb) *htb = &headers->htb; if (htb) { k = kh_get (rspamd_mime_headers_htb, htb, (gchar *) field); @@ -1621,18 +1628,43 @@ struct rspamd_mime_header * rspamd_message_get_header_array (struct rspamd_task *task, const gchar *field) { - return rspamd_message_get_header_from_hash (MESSAGE_FIELD_CHECK (task, raw_headers), + return rspamd_message_get_header_from_hash ( + MESSAGE_FIELD_CHECK (task, raw_headers), field); } +static void +rspamd_message_headers_dtor (struct rspamd_mime_headers_table *hdrs) +{ + if (hdrs) { + kfree (hdrs->htb.keys); + kfree (hdrs->htb.vals); + kfree (hdrs->htb.flags); + g_free (hdrs); + } +} + +struct rspamd_mime_headers_table * +rspamd_message_headers_ref (struct rspamd_mime_headers_table *hdrs) +{ + REF_RETAIN (hdrs); + + return hdrs; +} + void -rspamd_message_headers_destroy (khash_t(rspamd_mime_headers_htb) *htb) +rspamd_message_headers_unref (struct rspamd_mime_headers_table *hdrs) { - kh_destroy (rspamd_mime_headers_htb, htb); + REF_RELEASE (hdrs); } -khash_t(rspamd_mime_headers_htb) * +struct rspamd_mime_headers_table * rspamd_message_headers_new (void) { - return kh_init (rspamd_mime_headers_htb); + struct rspamd_mime_headers_table *nhdrs; + + nhdrs = g_malloc0 (sizeof (*nhdrs)); + REF_INIT_RETAIN (nhdrs, rspamd_message_headers_dtor); + + return nhdrs; } \ No newline at end of file diff --git a/src/libmime/mime_headers.h b/src/libmime/mime_headers.h index f9aa555c5..18d23d662 100644 --- a/src/libmime/mime_headers.h +++ b/src/libmime/mime_headers.h @@ -64,8 +64,7 @@ struct rspamd_mime_header { struct rspamd_mime_header *ord_next; /* Overall order of headers, slist */ }; -/* Define hash type */ -__KHASH_TYPE (rspamd_mime_headers_htb, gchar *, struct rspamd_mime_header *) +struct rspamd_mime_headers_table; enum rspamd_received_type { RSPAMD_RECEIVED_SMTP = 1u << 0u, @@ -119,7 +118,7 @@ struct rspamd_received_header { * @param check_newlines */ void rspamd_mime_headers_process (struct rspamd_task *task, - khash_t(rspamd_mime_headers_htb) *target, + struct rspamd_mime_headers_table *target, struct rspamd_mime_header **order_ptr, const gchar *in, gsize len, gboolean check_newlines); @@ -166,20 +165,22 @@ rspamd_message_get_header_array (struct rspamd_task *task, * @return An array of header's values or NULL. It is NOT permitted to free array or values. */ struct rspamd_mime_header * -rspamd_message_get_header_from_hash (khash_t(rspamd_mime_headers_htb) *htb, +rspamd_message_get_header_from_hash (struct rspamd_mime_headers_table *hdrs, const gchar *field); /** * Cleans up hash table of the headers * @param htb */ -void rspamd_message_headers_destroy (khash_t(rspamd_mime_headers_htb) *htb); +void rspamd_message_headers_unref (struct rspamd_mime_headers_table *hdrs); + +struct rspamd_mime_headers_table * rspamd_message_headers_ref (struct rspamd_mime_headers_table *hdrs); /** * Init headers hash * @return */ -khash_t(rspamd_mime_headers_htb)* rspamd_message_headers_new (void); +struct rspamd_mime_headers_table* rspamd_message_headers_new (void); #ifdef __cplusplus } diff --git a/src/libmime/mime_parser.c b/src/libmime/mime_parser.c index c075857b4..5d1ff1b77 100644 --- a/src/libmime/mime_parser.c +++ b/src/libmime/mime_parser.c @@ -258,7 +258,7 @@ rspamd_mime_part_get_cte_heuristic (struct rspamd_task *task, static void rspamd_mime_part_get_cte (struct rspamd_task *task, - khash_t(rspamd_mime_headers_htb) *hdrs, + struct rspamd_mime_headers_table *hdrs, struct rspamd_mime_part *part, gboolean apply_heuristic) { -- 2.39.5