]> source.dussan.org Git - rspamd.git/commitdiff
[Fix] Preserve order of options in symbols
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 22 Mar 2017 14:08:26 +0000 (14:08 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 22 Mar 2017 14:08:26 +0000 (14:08 +0000)
src/libmime/filter.c
src/libmime/filter.h
src/libserver/protocol.c
src/libserver/task.c
src/lua/lua_task.c

index 9d094d9acf84080f637b9f3bebf83c4edf32354a..1356cca20221c17a82189e03fc14a4efa511d644 100644 (file)
@@ -21,6 +21,7 @@
 #include "lua/lua_common.h"
 #include "cryptobox.h"
 #include <math.h>
+#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;
        }
 
index 920009d9cbcbbcdf9e2b9cc1e223d710f1d12141..3d8fa38a894d291d35fefd8055a211e622f8b983 100644 (file)
@@ -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;
index dfc590a78b7e5a4416d95bb15ea2e4f9a60bdd2b..d9e4f9b7b5ea9709dff0311d7820c8d061d4ae21 100644 (file)
@@ -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 <math.h>
@@ -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;
index 4d20edb834b8c2ca77a7ea3fb9066c2d90377f41..cbd9a7a315298e144ab7be06fa1cfe9aba316d78 100644 (file)
@@ -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, "...;");
index 3460aebcbb7adea8406a381912bdbc864f07ad18..f4d7f9dd6595c0fb1de5cbfc5ab86b3c782571a9 100644 (file)
@@ -27,6 +27,7 @@
 #include "cryptobox.h"
 #include "unix-std.h"
 #include "libmime/smtp_parsers.h"
+#include "contrib/uthash/utlist.h"
 #include <math.h>
 
 /***
@@ -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++);
                        }