]> git.ipfire.org Git - thirdparty/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:23:34 +0000 (16:23 +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 3a3203ed9162d3bb8e849d0e87b775bd046585d4..81a0159361485c552e8304b4e5ac01379e545d9b 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 bf90dd7b359e2274b12716c97a89bfb6c4781796..af7495b237429c3f2362eac03537657dd0cee31c 100644 (file)
@@ -98,7 +98,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";
 
@@ -448,6 +448,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 8aeb7dc6bd848630004dc80e3d120f53206abf62..8b0fdb999f64d569dca7a603745b2d8ec9bdf9e3 100644 (file)
@@ -178,7 +178,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 a8b08cc518e46df3e203f860d7b4a8640f81ddfd..fb84c4988fa0fa66fe8890188e8a6841d1fbe5d0 100644 (file)
@@ -779,6 +779,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);
        }
 }