diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-05-03 16:23:34 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-05-03 16:23:34 +0100 |
commit | 5dea259459069c35a6afe94304810fe5365cd819 (patch) | |
tree | c25ca862bf77d89ee17e69fa19b95199e4f14cac | |
parent | c7ae2de0541e0772b08cf4121fbfbd83aa1235d2 (diff) | |
download | rspamd-5dea259459069c35a6afe94304810fe5365cd819.tar.gz rspamd-5dea259459069c35a6afe94304810fe5365cd819.zip |
[CritFix] Restore the intended pre-filters behaviour
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).
-rw-r--r-- | src/libmime/filter.c | 38 | ||||
-rw-r--r-- | src/libserver/task.c | 9 | ||||
-rw-r--r-- | src/libserver/task.h | 2 | ||||
-rw-r--r-- | src/lua/lua_config.c | 6 |
4 files changed, 43 insertions, 12 deletions
diff --git a/src/libmime/filter.c b/src/libmime/filter.c index 3a3203ed9..81a015936 100644 --- a/src/libmime/filter.c +++ b/src/libmime/filter.c @@ -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) { diff --git a/src/libserver/task.c b/src/libserver/task.c index bf90dd7b3..af7495b23 100644 --- a/src/libserver/task.c +++ b/src/libserver/task.c @@ -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: diff --git a/src/libserver/task.h b/src/libserver/task.h index 8aeb7dc6b..8b0fdb999 100644 --- a/src/libserver/task.h +++ b/src/libserver/task.h @@ -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 */ diff --git a/src/lua/lua_config.c b/src/lua/lua_config.c index a8b08cc51..fb84c4988 100644 --- a/src/lua/lua_config.c +++ b/src/lua/lua_config.c @@ -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); } } |