]> source.dussan.org Git - rspamd.git/commitdiff
[CritFix] Restore the intended pre-filters behaviour
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 3 May 2016 15:23:34 +0000 (16:23 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 3 May 2016 15:50:43 +0000 (16:50 +0100)
Previously, filters and post-filters were checked even if pre-filter has
set some result. Now pre-result efficienly makes a trapdoor to writing
reply (as it was before 1.0).

src/libmime/filter.c
src/libserver/task.c
src/libserver/task.h
src/lua/lua_config.c

index b0f93ec4b8ac30bf6649f42ea4c9e53c8fa2deea..8314e8dc2de4ca4dae1906c940510c983ba9f2ae 100644 (file)
@@ -346,23 +346,41 @@ enum rspamd_metric_action
 rspamd_check_action_metric (struct rspamd_task *task, struct metric_result *mres)
 {
        struct metric_action *action, *selected_action = NULL;
-       double max_score = 0;
+       double max_score = 0, sc;
        int i;
 
-       for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i++) {
-               double sc;
+       if (task->pre_result.action == METRIC_ACTION_MAX) {
+               for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i++) {
+                       action = &mres->metric->actions[i];
+                       sc = mres->actions_limits[i];
 
-               action = &mres->metric->actions[i];
-               sc = mres->actions_limits[i];
+                       if (isnan (sc)) {
+                               continue;
+                       }
 
-               if (isnan (sc)) {
-                       continue;
+                       if (mres->score >= sc && sc > max_score) {
+                               selected_action = action;
+                               max_score = sc;
+                       }
                }
+       }
+       else {
+               i = task->pre_result.action;
+               selected_action = &mres->metric->actions[i];
+               sc = mres->actions_limits[i];
+
+               while (isnan (sc)) {
+                       i = (i + 1) % METRIC_ACTION_MAX;
+                       sc = mres->actions_limits[i];
 
-               if (mres->score >= sc && sc > max_score) {
-                       selected_action = action;
-                       max_score = sc;
+                       if (i == task->pre_result.action) {
+                               /* No scores defined, just avoid NaN */
+                               sc = 0;
+                               break;
+                       }
                }
+
+               mres->score = sc;
        }
 
        if (selected_action) {
index 44e67a328da6cb28aea1be9bb1efda29e1e1fea6..c96104b2afd2f0adb61bff51f29a948f2e1afcd7 100644 (file)
@@ -97,7 +97,7 @@ rspamd_task_new (struct rspamd_worker *worker, struct rspamd_config *cfg)
 
        new_task->sock = -1;
        new_task->flags |= (RSPAMD_TASK_FLAG_MIME|RSPAMD_TASK_FLAG_JSON);
-       new_task->pre_result.action = METRIC_ACTION_NOACTION;
+       new_task->pre_result.action = METRIC_ACTION_MAX;
 
        new_task->message_id = new_task->queue_id = "undef";
 
@@ -439,6 +439,13 @@ rspamd_task_process (struct rspamd_task *task, guint stages)
 
        case RSPAMD_TASK_STAGE_PRE_FILTERS:
                rspamd_lua_call_pre_filters (task);
+
+               if (task->pre_result.action != METRIC_ACTION_MAX) {
+                       /* Skip all if we have result here */
+                       task->processed_stages |= RSPAMD_TASK_STAGE_DONE;
+                       msg_info_task ("skip filters, as pre-filter returned %s action",
+                                       rspamd_action_to_str (task->pre_result.action));
+               }
                break;
 
        case RSPAMD_TASK_STAGE_FILTERS:
index c27d4bcb5d42d416e7d45d7201785dc2e6fd25cc..75af296608d2022576cb3602651d33db1054e903 100644 (file)
@@ -172,7 +172,7 @@ struct rspamd_task {
        gpointer checkpoint;                                                    /**< Opaque checkpoint data                                                     */
 
        struct {
-               guint32 action;                                                         /**< Action of pre filters                                                      */
+               gint action;                                                            /**< Action of pre filters                                                      */
                gchar *str;                                                                     /**< String describing action                                           */
        } pre_result;                                                                   /**< Result of pre-filters                                                      */
 
index 7d63928187dde948560737aaef558145d6def2d9..a6ede8efa473631f2afb16b2f93b15db13246c79 100644 (file)
@@ -744,6 +744,12 @@ rspamd_lua_call_pre_filters (struct rspamd_task *task)
                                lua_tostring (cd->L, -1));
                        lua_pop (cd->L, 1);
                }
+
+               if (task->pre_result.action != METRIC_ACTION_MAX) {
+                       /* Stop processing on reaching some pre-result */
+                       break;
+               }
+
                cur = g_list_next (cur);
        }
 }