From 4bd85f81c36c54a68f3abeb9c7641ed0b042c978 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 3 May 2016 16:23:34 +0100 Subject: [PATCH] [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). --- src/libmime/filter.c | 38 ++++++++++++++++++++++++++++---------- src/libserver/task.c | 9 ++++++++- src/libserver/task.h | 2 +- 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 b0f93ec4b..8314e8dc2 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 44e67a328..c96104b2a 100644 --- a/src/libserver/task.c +++ b/src/libserver/task.c @@ -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: diff --git a/src/libserver/task.h b/src/libserver/task.h index c27d4bcb5..75af29660 100644 --- a/src/libserver/task.h +++ b/src/libserver/task.h @@ -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 */ diff --git a/src/lua/lua_config.c b/src/lua/lua_config.c index 7d6392818..a6ede8efa 100644 --- a/src/lua/lua_config.c +++ b/src/lua/lua_config.c @@ -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); } } -- 2.39.5