aboutsummaryrefslogtreecommitdiffstats
path: root/src/libutil/expression.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-04-12 11:56:49 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-04-12 11:56:49 +0100
commit5134580d74d1249470935b809528d281feaddf84 (patch)
tree3c8414f878c7cf39229ac063062a296934599e52 /src/libutil/expression.c
parentb79037baae40fec378c98d9e89c11798adf5691f (diff)
downloadrspamd-5134580d74d1249470935b809528d281feaddf84.tar.gz
rspamd-5134580d74d1249470935b809528d281feaddf84.zip
[CritFix] Fix issue with expressions processing
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.
Diffstat (limited to 'src/libutil/expression.c')
-rw-r--r--src/libutil/expression.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/src/libutil/expression.c b/src/libutil/expression.c
index 1ab06e388..618adad49 100644
--- a/src/libutil/expression.c
+++ b/src/libutil/expression.c
@@ -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)) {