]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Fix] Fix mas group score calculations
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 23 Jan 2017 17:16:43 +0000 (17:16 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 23 Jan 2017 17:16:43 +0000 (17:16 +0000)
src/libmime/filter.c

index d116ccb45326061fa0d283e3a2fe198fb8e2fb0c..b16fdfafac5206f54b346abae4efc6e9cdb83369 100644 (file)
@@ -70,6 +70,28 @@ rspamd_create_metric_result (struct rspamd_task *task, const gchar *name)
        return metric_res;
 }
 
+static inline gdouble
+rspamd_check_group_score (struct rspamd_task *task,
+               const gchar *symbol,
+               struct rspamd_symbols_group *gr,
+               gdouble *group_score,
+               gdouble w)
+{
+       if (gr != NULL && group_score && gr->max_score > 0.0) {
+               if (*group_score >= gr->max_score && w > 0) {
+                       msg_info_task ("maximum group score %.2f for group %s has been reached,"
+                                       " ignoring symbol %s with weight %.2f", gr->max_score,
+                                       gr->name, symbol, w);
+                       return NAN;
+               }
+               else if (*group_score + w > gr->max_score) {
+                       w = gr->max_score - *group_score;
+               }
+       }
+
+       return w;
+}
+
 static struct rspamd_symbol_result *
 insert_metric_result (struct rspamd_task *task,
        struct rspamd_metric *metric,
@@ -80,7 +102,7 @@ insert_metric_result (struct rspamd_task *task,
 {
        struct rspamd_metric_result *metric_res;
        struct rspamd_symbol_result *s = NULL;
-       gdouble w, *gr_score = NULL;
+       gdouble w, *gr_score = NULL, next_gf = 1.0, diff;
        struct rspamd_symbol *sdef;
        struct rspamd_symbols_group *gr = NULL;
        const ucl_object_t *mobj, *sobj;
@@ -118,21 +140,6 @@ insert_metric_result (struct rspamd_task *task,
                }
        }
 
-       /* XXX: does not take grow factor into account */
-       if (gr != NULL && gr_score != NULL && gr->max_score > 0.0) {
-               if (*gr_score >= gr->max_score) {
-                       msg_info_task ("maximum group score %.2f for group %s has been reached,"
-                                       " ignoring symbol %s with weight %.2f", gr->max_score,
-                                       gr->name, symbol, w);
-                       return g_hash_table_lookup (metric_res->symbols, symbol);
-               }
-               else if (*gr_score + w > gr->max_score) {
-                       w = gr->max_score - *gr_score;
-               }
-
-               *gr_score += w;
-       }
-
        /* Add metric score */
        if ((s = g_hash_table_lookup (metric_res->symbols, symbol)) != NULL) {
                if (sdef && (sdef->flags & RSPAMD_SYMBOL_FLAG_ONESHOT)) {
@@ -145,19 +152,44 @@ insert_metric_result (struct rspamd_task *task,
 
                if (rspamd_task_add_result_option (task, s, opt)) {
                        if (!single) {
-                               /* Handle grow factor */
-                               if (metric_res->grow_factor && w > 0) {
-                                       w *= metric_res->grow_factor;
-                                       metric_res->grow_factor *= metric->grow_factor;
-                               }
-                               s->score += w;
-                               metric_res->score += w;
+                               diff = w;
                        }
                        else {
                                if (fabs (s->score) < fabs (w)) {
                                        /* Replace less weight with a bigger one */
-                                       metric_res->score = metric_res->score - s->score + w;
-                                       s->score = w;
+                                       diff = metric_res->score - s->score + w;
+                               }
+                               else {
+                                       diff = 0;
+                               }
+                       }
+
+                       if (diff) {
+                               /* Handle grow factor */
+                               if (metric_res->grow_factor && diff > 0) {
+                                       diff *= metric_res->grow_factor;
+                                       next_gf *= metric->grow_factor;
+                               }
+                               else if (diff > 0) {
+                                       next_gf = metric->grow_factor;
+                               }
+
+                               diff = rspamd_check_group_score (task, symbol, gr, gr_score, diff);
+
+                               if (!isnan (w)) {
+                                       metric_res->score += diff;
+                                       metric_res->grow_factor = next_gf;
+
+                                       if (gr_score) {
+                                               *gr_score += diff;
+                                       }
+
+                                       if (single) {
+                                               s->score = w;
+                                       }
+                                       else {
+                                               s->score += diff;
+                                       }
                                }
                        }
                }
@@ -168,16 +200,30 @@ insert_metric_result (struct rspamd_task *task,
                /* Handle grow factor */
                if (metric_res->grow_factor && w > 0) {
                        w *= metric_res->grow_factor;
-                       metric_res->grow_factor *= metric->grow_factor;
+                       next_gf *= metric->grow_factor;
                }
                else if (w > 0) {
-                       metric_res->grow_factor = metric->grow_factor;
+                       next_gf = metric->grow_factor;
                }
 
-               s->score = w;
                s->name = symbol;
                s->sym = sdef;
-               metric_res->score += w;
+
+               w = rspamd_check_group_score (task, symbol, gr, gr_score, w);
+
+               if (!isnan (w)) {
+                       metric_res->score += w;
+                       metric_res->grow_factor = next_gf;
+                       s->score = w;
+
+                       if (gr_score) {
+                               *gr_score += w;
+                       }
+
+               }
+               else {
+                       s->score = 0;
+               }
 
                rspamd_task_add_result_option (task, s, opt);
                g_hash_table_insert (metric_res->symbols, (gpointer) symbol, s);