From b0bc4a9e9c89e4976e7a14f18d0595ec2b6e8213 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Sat, 30 Sep 2017 11:32:54 +0100 Subject: [PATCH] [Rework] Use floating point arithmetics in Rspamd expressions --- src/libmime/mime_expressions.c | 6 +++--- src/libserver/composites.c | 4 ++-- src/libutil/expression.c | 39 +++++++++++++++++----------------- src/libutil/expression.h | 6 +++--- src/lua/lua_expression.c | 8 +++---- 5 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/libmime/mime_expressions.c b/src/libmime/mime_expressions.c index 7e6816170..329f80f95 100644 --- a/src/libmime/mime_expressions.c +++ b/src/libmime/mime_expressions.c @@ -83,7 +83,7 @@ static gboolean rspamd_is_empty_body (struct rspamd_task *task, static rspamd_expression_atom_t * rspamd_mime_expr_parse (const gchar *line, gsize len, rspamd_mempool_t *pool, gpointer ud, GError **err); -static gint rspamd_mime_expr_process (gpointer input, rspamd_expression_atom_t *atom); +static gdouble rspamd_mime_expr_process (gpointer input, rspamd_expression_atom_t *atom); static gint rspamd_mime_expr_priority (rspamd_expression_atom_t *atom); static void rspamd_mime_expr_destroy (rspamd_expression_atom_t *atom); @@ -912,13 +912,13 @@ rspamd_mime_expr_process_function (struct rspamd_function_atom * func, return selected->func (task, func->args, selected->user_data); } -static gint +static gdouble rspamd_mime_expr_process (gpointer input, rspamd_expression_atom_t *atom) { struct rspamd_task *task = input; struct rspamd_mime_atom *mime_atom; lua_State *L; - gint ret = 0; + gdouble ret = 0; g_assert (task != NULL); g_assert (atom != NULL); diff --git a/src/libserver/composites.c b/src/libserver/composites.c index 7aee6a230..bf573ada7 100644 --- a/src/libserver/composites.c +++ b/src/libserver/composites.c @@ -46,7 +46,7 @@ struct symbol_remove_data { static rspamd_expression_atom_t * rspamd_composite_expr_parse (const gchar *line, gsize len, rspamd_mempool_t *pool, gpointer ud, GError **err); -static gint rspamd_composite_expr_process (gpointer input, rspamd_expression_atom_t *atom); +static gdouble rspamd_composite_expr_process (gpointer input, rspamd_expression_atom_t *atom); static gint rspamd_composite_expr_priority (rspamd_expression_atom_t *atom); static void rspamd_composite_expr_destroy (rspamd_expression_atom_t *atom); @@ -132,7 +132,7 @@ rspamd_composite_process_single_symbol (struct composites_data *cd, return rc; } -static gint +static gdouble rspamd_composite_expr_process (gpointer input, rspamd_expression_atom_t *atom) { struct composites_data *cd = (struct composites_data *)input; diff --git a/src/libutil/expression.c b/src/libutil/expression.c index 6ee6ccb67..b49935cb4 100644 --- a/src/libutil/expression.c +++ b/src/libutil/expression.c @@ -20,12 +20,14 @@ #include "util.h" #include "utlist.h" #include "ottery.h" +#include #define RSPAMD_EXPR_FLAG_NEGATE (1 << 0) #define RSPAMD_EXPR_FLAG_PROCESSED (1 << 1) #define MIN_RESORT_EVALS 50 #define MAX_RESORT_EVALS 150 +#define DOUBLE_EPSILON 1e-9 enum rspamd_expression_elt_type { ELT_OP = 0, @@ -44,7 +46,7 @@ struct rspamd_expression_elt { } lim; } p; gint flags; - gint value; + gdouble value; gint priority; }; @@ -879,7 +881,7 @@ err: static gboolean rspamd_ast_node_done (struct rspamd_expression_elt *elt, - struct rspamd_expression_elt *parelt, gint acc, gint lim) + struct rspamd_expression_elt *parelt, gdouble acc, gdouble lim) { gboolean ret = FALSE; @@ -939,17 +941,17 @@ rspamd_ast_node_done (struct rspamd_expression_elt *elt, return ret; } -static gint +static gdouble rspamd_ast_do_op (struct rspamd_expression_elt *elt, gint val, - gint acc, gint lim, gboolean first_elt) + gdouble acc, gdouble lim, gboolean first_elt) { - gint ret = val; + gdouble ret = val; g_assert (elt->type == ELT_OP); switch (elt->p.op) { case OP_NOT: - ret = !val; + ret = fabs (val) > DOUBLE_EPSILON ? 0.0 : 1.0; break; case OP_PLUS: ret = acc + val; @@ -968,10 +970,10 @@ rspamd_ast_do_op (struct rspamd_expression_elt *elt, gint val, break; case OP_MULT: case OP_AND: - ret = first_elt ? (val) : (acc && val); + ret = first_elt ? (val) : (acc * val); break; case OP_OR: - ret = first_elt ? (val) : (acc || val); + ret = first_elt ? (val) : (acc + val); break; default: g_assert (0); @@ -981,14 +983,14 @@ rspamd_ast_do_op (struct rspamd_expression_elt *elt, gint val, return ret; } -static gint +static gdouble rspamd_ast_process_node (struct rspamd_expression *expr, gint flags, GNode *node, gpointer data, GPtrArray *track) { struct rspamd_expression_elt *elt, *celt, *parelt = NULL; GNode *cld; - gint acc = G_MININT, lim = G_MININT, val; - gdouble t1, t2; + gdouble acc = NAN, lim = 0; + gdouble t1, t2, val; gboolean calc_ticks = FALSE; elt = node->data; @@ -1010,7 +1012,7 @@ rspamd_ast_process_node (struct rspamd_expression *expr, gint flags, GNode *node elt->value = expr->subr->process (data, elt->p.atom); - if (elt->value) { + if (fabs (elt->value) > 1e-9) { elt->p.atom->hits ++; if (track) { @@ -1027,15 +1029,14 @@ rspamd_ast_process_node (struct rspamd_expression *expr, gint flags, GNode *node elt->flags |= RSPAMD_EXPR_FLAG_PROCESSED; } - return elt->value; + acc = elt->value; break; case ELT_LIMIT: - return elt->p.lim.val; + acc = elt->p.lim.val; break; case ELT_OP: g_assert (node->children != NULL); - cld = node->children; /* Try to find limit at the parent node */ if (node->parent) { @@ -1058,7 +1059,7 @@ rspamd_ast_process_node (struct rspamd_expression *expr, gint flags, GNode *node val = rspamd_ast_process_node (expr, flags, cld, data, track); - if (acc == G_MININT) { + if (isnan (acc)) { acc = rspamd_ast_do_op (elt, val, 0, lim, TRUE); } else { @@ -1088,11 +1089,11 @@ rspamd_ast_cleanup_traverse (GNode *n, gpointer d) return FALSE; } -gint +gdouble rspamd_process_expression_track (struct rspamd_expression *expr, gint flags, gpointer data, GPtrArray *track) { - gint ret = 0; + gdouble ret = 0; g_assert (expr != NULL); /* Ensure that stack is empty at this point */ @@ -1122,7 +1123,7 @@ rspamd_process_expression_track (struct rspamd_expression *expr, gint flags, return ret; } -gint +gdouble rspamd_process_expression (struct rspamd_expression *expr, gint flags, gpointer data) { diff --git a/src/libutil/expression.h b/src/libutil/expression.h index 2c0ec7497..fefde2974 100644 --- a/src/libutil/expression.h +++ b/src/libutil/expression.h @@ -61,7 +61,7 @@ struct rspamd_atom_subr { rspamd_expression_atom_t * (*parse)(const gchar *line, gsize len, rspamd_mempool_t *pool, gpointer ud, GError **err); /* Process atom via the opaque pointer (e.g. struct rspamd_task *) */ - gint (*process) (gpointer input, rspamd_expression_atom_t *atom); + gdouble (*process) (gpointer input, rspamd_expression_atom_t *atom); /* Calculates the relative priority of the expression */ gint (*priority) (rspamd_expression_atom_t *atom); void (*destroy) (rspamd_expression_atom_t *atom); @@ -92,7 +92,7 @@ gboolean rspamd_parse_expression (const gchar *line, gsize len, * @param data opaque data pointer for all the atoms * @return the value of expression */ -gint rspamd_process_expression (struct rspamd_expression *expr, gint flags, +gdouble rspamd_process_expression (struct rspamd_expression *expr, gint flags, gpointer data); /** @@ -103,7 +103,7 @@ gint rspamd_process_expression (struct rspamd_expression *expr, gint flags, * @param track pointer array to atoms tracking * @return the value of expression */ -gint rspamd_process_expression_track (struct rspamd_expression *expr, gint flags, +gdouble rspamd_process_expression_track (struct rspamd_expression *expr, gint flags, gpointer data, GPtrArray *track); /** diff --git a/src/lua/lua_expression.c b/src/lua/lua_expression.c index 7bacf5a75..7975cc227 100644 --- a/src/lua/lua_expression.c +++ b/src/lua/lua_expression.c @@ -98,7 +98,7 @@ static const struct luaL_reg exprlib_f[] = { static rspamd_expression_atom_t * lua_atom_parse (const gchar *line, gsize len, rspamd_mempool_t *pool, gpointer ud, GError **err); -static gint lua_atom_process (gpointer input, rspamd_expression_atom_t *atom); +static gdouble lua_atom_process (gpointer input, rspamd_expression_atom_t *atom); static const struct rspamd_atom_subr lua_atom_subr = { .parse = lua_atom_parse, @@ -165,11 +165,11 @@ lua_atom_parse (const gchar *line, gsize len, return atom; } -static gint +static gdouble lua_atom_process (gpointer input, rspamd_expression_atom_t *atom) { struct lua_expression *e = (struct lua_expression *)atom->data; - gint ret = 0; + gdouble ret = 0; lua_rawgeti (e->L, LUA_REGISTRYINDEX, e->process_idx); lua_pushlstring (e->L, atom->str, atom->len); @@ -191,7 +191,7 @@ static gint lua_expr_process (lua_State *L) { struct lua_expression *e = rspamd_lua_expression (L, 1); - gint res; + gdouble res; gint flags = 0; if (lua_gettop (L) >= 3) { -- 2.39.5