From: Vsevolod Stakhov Date: Wed, 22 Mar 2017 14:08:26 +0000 (+0000) Subject: [Fix] Preserve order of options in symbols X-Git-Tag: 1.5.4~65 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7849cfa0767a48fd6cfbf0b41f5a42c4352a0e87;p=thirdparty%2Frspamd.git [Fix] Preserve order of options in symbols --- diff --git a/src/libmime/filter.c b/src/libmime/filter.c index 9d094d9acf..1356cca202 100644 --- a/src/libmime/filter.c +++ b/src/libmime/filter.c @@ -21,6 +21,7 @@ #include "lua/lua_common.h" #include "cryptobox.h" #include +#include "contrib/uthash/utlist.h" #define COMMON_PART_FACTOR 95 @@ -318,19 +319,22 @@ rspamd_task_insert_result_single (struct rspamd_task *task, gboolean rspamd_task_add_result_option (struct rspamd_task *task, - struct rspamd_symbol_result *s, const gchar *opt) + struct rspamd_symbol_result *s, const gchar *val) { - char *opt_cpy; + struct rspamd_symbol_option *opt; gboolean ret = FALSE; - if (s && opt) { + if (s && val) { if (s->options && !(s->sym && (s->sym->flags & RSPAMD_SYMBOL_FLAG_ONEPARAM)) && g_hash_table_size (s->options) < task->cfg->default_max_shots) { /* Append new options */ - if (!g_hash_table_lookup (s->options, opt)) { - opt_cpy = rspamd_mempool_strdup (task->task_pool, opt); - g_hash_table_insert (s->options, opt_cpy, opt_cpy); + if (!g_hash_table_lookup (s->options, val)) { + opt = rspamd_mempool_alloc (task->task_pool, sizeof (*opt)); + opt->option = rspamd_mempool_strdup (task->task_pool, val); + DL_APPEND (s->opts_head, opt); + + g_hash_table_insert (s->options, opt->option, opt); ret = TRUE; } } @@ -340,12 +344,16 @@ rspamd_task_add_result_option (struct rspamd_task *task, rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t)g_hash_table_unref, s->options); - opt_cpy = rspamd_mempool_strdup (task->task_pool, opt); - g_hash_table_insert (s->options, opt_cpy, opt_cpy); + opt = rspamd_mempool_alloc (task->task_pool, sizeof (*opt)); + opt->option = rspamd_mempool_strdup (task->task_pool, val); + s->opts_head = NULL; + DL_APPEND (s->opts_head, opt); + + g_hash_table_insert (s->options, opt->option, opt); ret = TRUE; } } - else if (!opt) { + else if (!val) { ret = TRUE; } diff --git a/src/libmime/filter.h b/src/libmime/filter.h index 920009d9cb..3d8fa38a89 100644 --- a/src/libmime/filter.h +++ b/src/libmime/filter.h @@ -14,12 +14,18 @@ struct rspamd_task; struct rspamd_settings; struct rspamd_classifier_config; +struct rspamd_symbol_option { + gchar *option; + struct rspamd_symbol_option *prev, *next; +}; + /** * Rspamd symbol */ struct rspamd_symbol_result { double score; /**< symbol's score */ GHashTable *options; /**< list of symbol's options */ + struct rspamd_symbol_option *opts_head; /**< head of linked list of options */ const gchar *name; struct rspamd_symbol *sym; /**< symbol configuration */ guint nshots; diff --git a/src/libserver/protocol.c b/src/libserver/protocol.c index dfc590a78b..d9e4f9b7b5 100644 --- a/src/libserver/protocol.c +++ b/src/libserver/protocol.c @@ -26,6 +26,7 @@ #include "worker_private.h" #include "cryptobox.h" #include "contrib/zstd/zstd.h" +#include "contrib/uthash/utlist.h" #include "lua/lua_common.h" #include "unix-std.h" #include @@ -857,8 +858,9 @@ static ucl_object_t * rspamd_metric_symbol_ucl (struct rspamd_task *task, struct rspamd_metric *m, struct rspamd_symbol_result *sym) { - ucl_object_t *obj = NULL; + ucl_object_t *obj = NULL, *ar; const gchar *description = NULL; + struct rspamd_symbol_option *opt; if (sym->sym != NULL) { description = sym->sym->description; @@ -874,8 +876,13 @@ rspamd_metric_symbol_ucl (struct rspamd_task *task, struct rspamd_metric *m, description), "description", 0, false); } if (sym->options != NULL) { - ucl_object_insert_key (obj, rspamd_str_hash_ucl (sym->options), - "options", 0, false); + ar = ucl_object_typed_new (UCL_ARRAY); + + DL_FOREACH (sym->opts_head, opt) { + ucl_array_append (ar, ucl_object_fromstring (opt->option)); + } + + ucl_object_insert_key (obj, ar, "options", 0, false); } return obj; diff --git a/src/libserver/task.c b/src/libserver/task.c index 4d20edb834..cbd9a7a315 100644 --- a/src/libserver/task.c +++ b/src/libserver/task.c @@ -1031,19 +1031,15 @@ rspamd_task_log_metric_res (struct rspamd_task *task, } if (lf->flags & RSPAMD_LOG_FLAG_SYMBOLS_PARAMS) { - GHashTableIter it; - gpointer k, v; - rspamd_printf_fstring (&symbuf, "{"); if (sym->options) { - j = 0; - g_hash_table_iter_init (&it, sym->options); + struct rspamd_symbol_option *opt; - while (g_hash_table_iter_next (&it, &k, &v)) { - const char *opt = v; + j = 0; - rspamd_printf_fstring (&symbuf, "%s;", opt); + DL_FOREACH (sym->opts_head, opt) { + rspamd_printf_fstring (&symbuf, "%s;", opt->option); if (j >= max_log_elts) { rspamd_printf_fstring (&symbuf, "...;"); diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c index 3460aebcbb..f4d7f9dd65 100644 --- a/src/lua/lua_task.c +++ b/src/lua/lua_task.c @@ -27,6 +27,7 @@ #include "cryptobox.h" #include "unix-std.h" #include "libmime/smtp_parsers.h" +#include "contrib/uthash/utlist.h" #include /*** @@ -2745,6 +2746,7 @@ lua_push_symbol_result (lua_State *L, { struct rspamd_metric_result *metric_res; struct rspamd_symbol_result *s = NULL; + struct rspamd_symbol_option *opt; gint j = 1, e = 4; if (!symbol_result) { @@ -2793,15 +2795,11 @@ lua_push_symbol_result (lua_State *L, } if (s->options) { - GHashTableIter it; - gpointer k, v; - lua_pushstring (L, "options"); lua_createtable (L, g_hash_table_size (s->options), 0); - g_hash_table_iter_init (&it, s->options); - while (g_hash_table_iter_next (&it, &k, &v)) { - lua_pushstring (L, (const char*)v); + DL_FOREACH (s->opts_head, opt) { + lua_pushstring (L, (const char*)opt->option); lua_rawseti (L, -2, j++); }