]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Rework] Use floating point arithmetics in Rspamd expressions
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 30 Sep 2017 10:32:54 +0000 (11:32 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 30 Sep 2017 10:32:54 +0000 (11:32 +0100)
src/libmime/mime_expressions.c
src/libserver/composites.c
src/libutil/expression.c
src/libutil/expression.h
src/lua/lua_expression.c

index 7e6816170b4b8d73435a2a4d6e3fcc8db60efd91..329f80f9593f5d8e7cd2c47a9ed498ce6cef233e 100644 (file)
@@ -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);
index 7aee6a230f8574bce6f72ce43fbbfde1882ee2ed..bf573ada7fe99b4b7aaf9d97315add62d37bca8b 100644 (file)
@@ -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;
index 6ee6ccb67168fbef02496e7be27092327a6ecdf6..b49935cb440053228901fc72f26fbb8f7e562a8e 100644 (file)
 #include "util.h"
 #include "utlist.h"
 #include "ottery.h"
+#include <math.h>
 
 #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)
 {
index 2c0ec74977794b313c569ef8055f0b3108d4641a..fefde29740e3144e5ab1bd7a3973f68ba1303192 100644 (file)
@@ -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);
 
 /**
index 7bacf5a75d37a0d6317893e383aad2b81ed0968d..7975cc2273aa670a8312b05ac65f70b691e3ac03 100644 (file)
@@ -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) {