summaryrefslogtreecommitdiffstats
path: root/src/libutil/expression.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2018-10-09 12:36:23 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2018-10-09 12:36:23 +0100
commit01e6bf680b28286083ed4ccf359c394b7190ceb8 (patch)
tree6b0d11e39f1ef68efe4f2f377ca436e414ea075d /src/libutil/expression.c
parent7f04293f0b78bd177a16cb06d2004e9e7803259e (diff)
downloadrspamd-01e6bf680b28286083ed4ccf359c394b7190ceb8.tar.gz
rspamd-01e6bf680b28286083ed4ccf359c394b7190ceb8.zip
[Minor] Add more operations sanity check in expressions parser
Diffstat (limited to 'src/libutil/expression.c')
-rw-r--r--src/libutil/expression.c128
1 files changed, 70 insertions, 58 deletions
diff --git a/src/libutil/expression.c b/src/libutil/expression.c
index 65465ceb6..463e3165a 100644
--- a/src/libutil/expression.c
+++ b/src/libutil/expression.c
@@ -613,78 +613,90 @@ rspamd_parse_expression (const gchar *line, gsize len,
case PARSE_ATOM:
if (g_ascii_isspace (*p)) {
state = SKIP_SPACES;
+ continue;
}
else if (rspamd_expr_is_operation_symbol (*p)) {
+ if (p + 1 < end) {
+ gchar t = *(p + 1);
+
+ if (g_ascii_isspace (t) || g_ascii_isalnum (t) ||
+ rspamd_expr_is_operation_symbol (t)) {
+ state = PARSE_OP;
+ continue;
+ }
+ }
+ else {
+ state = PARSE_OP;
+ continue;
+ }
+ }
+
+ /*
+ * First of all, we check some pre-conditions:
+ * 1) if we have 'and ' or 'or ' or 'not ' strings, they are op
+ * 2) if we have full numeric string, then we check for
+ * the following expression:
+ * ^\d+\s*[><]$
+ */
+ if ((gulong)(end - p) > sizeof ("and ") &&
+ (g_ascii_strncasecmp (p, "and ", sizeof ("and ") - 1) == 0 ||
+ g_ascii_strncasecmp (p, "not ", sizeof ("not ") - 1) == 0 )) {
+ state = PARSE_OP;
+ }
+ else if ((gulong)(end - p) > sizeof ("or ") &&
+ g_ascii_strncasecmp (p, "or ", sizeof ("or ") - 1) == 0) {
state = PARSE_OP;
}
else {
/*
- * First of all, we check some pre-conditions:
- * 1) if we have 'and ' or 'or ' or 'not ' strings, they are op
- * 2) if we have full numeric string, then we check for
- * the following expression:
- * ^\d+\s*[><]$
+ * If we have any comparison operator in the stack, then try
+ * to parse limit
*/
- if ((gulong)(end - p) > sizeof ("and ") &&
- (g_ascii_strncasecmp (p, "and ", sizeof ("and ") - 1) == 0 ||
- g_ascii_strncasecmp (p, "not ", sizeof ("not ") - 1) == 0 )) {
- state = PARSE_OP;
- }
- else if ((gulong)(end - p) > sizeof ("or ") &&
- g_ascii_strncasecmp (p, "or ", sizeof ("or ") - 1) == 0) {
- state = PARSE_OP;
- }
- else {
- /*
- * If we have any comparison operator in the stack, then try
- * to parse limit
- */
- op = GPOINTER_TO_INT (rspamd_expr_stack_peek (e));
-
- if (op >= OP_LT && op <= OP_GE) {
- if (rspamd_regexp_search (num_re,
- p,
- end - p,
- NULL,
- NULL,
- FALSE,
- NULL)) {
- c = p;
- state = PARSE_LIM;
- continue;
- }
+ op = GPOINTER_TO_INT (rspamd_expr_stack_peek (e));
+
+ if (op >= OP_LT && op <= OP_GE) {
+ if (rspamd_regexp_search (num_re,
+ p,
+ end - p,
+ NULL,
+ NULL,
+ FALSE,
+ NULL)) {
+ c = p;
+ state = PARSE_LIM;
+ continue;
}
+ }
- /* Try to parse atom */
- atom = subr->parse (p, end - p, pool, subr_data, err);
- if (atom == NULL || atom->len == 0) {
- /* We couldn't parse the atom, so go out */
- if (err != NULL && *err == NULL) {
- g_set_error (err,
- rspamd_expr_quark (),
- 500,
- "Cannot parse atom: callback function failed"
- " to parse '%.*s'",
- (int) (end - p),
- p);
- }
- goto err;
+ /* Try to parse atom */
+ atom = subr->parse (p, end - p, pool, subr_data, err);
+ if (atom == NULL || atom->len == 0) {
+ /* We couldn't parse the atom, so go out */
+ if (err != NULL && *err == NULL) {
+ g_set_error (err,
+ rspamd_expr_quark (),
+ 500,
+ "Cannot parse atom: callback function failed"
+ " to parse '%.*s'",
+ (int) (end - p),
+ p);
}
+ goto err;
+ }
- if (atom->str == NULL) {
- atom->str = p;
- }
+ if (atom->str == NULL) {
+ atom->str = p;
+ }
- p = p + atom->len;
+ p = p + atom->len;
- /* Push to output */
- elt.type = ELT_ATOM;
- elt.p.atom = atom;
- g_array_append_val (e->expressions, elt);
- rspamd_expr_stack_elt_push (operand_stack,
- g_node_new (rspamd_expr_dup_elt (pool, &elt)));
+ /* Push to output */
+ elt.type = ELT_ATOM;
+ elt.p.atom = atom;
+ g_array_append_val (e->expressions, elt);
+ rspamd_expr_stack_elt_push (operand_stack,
+ g_node_new (rspamd_expr_dup_elt (pool, &elt)));
- }
}
break;
case PARSE_LIM: