]> source.dussan.org Git - rspamd.git/commitdiff
[CritFix] Fix issue with expressions processing
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 12 Apr 2016 10:56:49 +0000 (11:56 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 12 Apr 2016 10:56:49 +0000 (11:56 +0100)
If the first rule in A + B + C + D > X matched then it was counted like
`1 + 1` and not as `0 + 1` as the accumulator was incorrectly treated in
that case.

src/libutil/expression.c

index 1ab06e38831765ce84694a88d4de639883526c30..618adad49f31632defd0853a2b72640bb1f0ba82 100644 (file)
@@ -922,7 +922,8 @@ rspamd_ast_node_done (struct rspamd_expression_elt *elt,
 }
 
 static gint
-rspamd_ast_do_op (struct rspamd_expression_elt *elt, gint val, gint acc, gint lim)
+rspamd_ast_do_op (struct rspamd_expression_elt *elt, gint val,
+               gint acc, gint lim, gboolean first_elt)
 {
        gint ret = val;
 
@@ -936,23 +937,23 @@ rspamd_ast_do_op (struct rspamd_expression_elt *elt, gint val, gint acc, gint li
                ret = acc + val;
                break;
        case OP_GE:
-               ret = acc >= lim;
+               ret = first_elt ? (val >= lim) : (acc >= lim);
                break;
        case OP_GT:
-               ret = acc > lim;
+               ret = first_elt ? (val > lim) : (acc > lim);
                break;
        case OP_LE:
-               ret = acc <= lim;
+               ret = first_elt ? (val <= lim) : (acc <= lim);
                break;
        case OP_LT:
-               ret = acc < lim;
+               ret = first_elt ? (val < lim) : (acc < lim);
                break;
        case OP_MULT:
        case OP_AND:
-               ret = acc && val;
+               ret = first_elt ? (val) : (acc && val);
                break;
        case OP_OR:
-               ret = acc || val;
+               ret = first_elt ? (val) : (acc || val);
                break;
        default:
                g_assert (0);
@@ -1040,10 +1041,11 @@ 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) {
-                               acc = val;
+                               acc = rspamd_ast_do_op (elt, val, 0, lim, TRUE);
+                       }
+                       else {
+                               acc = rspamd_ast_do_op (elt, val, acc, lim, FALSE);
                        }
-
-                       acc = rspamd_ast_do_op (elt, val, acc, lim);
 
                        if (!(flags & RSPAMD_EXPRESSION_FLAG_NOOPT)) {
                                if (rspamd_ast_node_done (elt, parelt, acc, lim)) {