commit f8b9444: [Rework] Use opaque structure to store a table of mime headers

Vsevolod Stakhov vsevolod at highsecure.ru
Tue Aug 13 10:35:06 UTC 2019


Author: Vsevolod Stakhov
Date: 2019-08-13 11:24:04 +0100
URL: https://github.com/rspamd/rspamd/commit/f8b94440fdc5cdde583832ab1daabd7ef84f3831

[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 <unicode/utf8.h>
 
-__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)
 {


More information about the Commits mailing list