From f0ca30b60b89ce601253a0653ffcd01cd8bcb516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Valverde?= Date: Fri, 1 Apr 2022 18:44:15 +0100 Subject: [PATCH] dfilter: More arithmetic fixes Fix a failed assertion with constant arithmetic expressions. Because we do not parse constants on the lexical level it is more complicated to handle constant expressions with unparsed values. We need to handle missing type information gracefully for any kind of arithmetic expression, not just unary minus. --- epan/dfilter/semcheck.c | 19 +++++++------------ test/suite_dfilter/group_syntax.py | 11 ++++++++++- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c index 2fa0f0f27e..3bd4845db1 100644 --- a/epan/dfilter/semcheck.c +++ b/epan/dfilter/semcheck.c @@ -1017,20 +1017,9 @@ check_relation_LHS_ARITHMETIC(dfwork_t *dfw, test_op_t st_op _U_, { stnode_t *entity; sttype_id_t entity_type; - test_op_t st_op_math; LOG_NODE(st_node); - sttype_test_get(st_arg1, &st_op_math, &entity, NULL); - resolve_unparsed(dfw, entity); - - /* Check if we have a unary minus with a constant. That's not valid - * on the LHS. */ - if (st_op_math == OP_UNARY_MINUS && node_is_constant(entity)) { - FAIL(dfw, "Left side of %s expression must be a field or function, not %s.", - stnode_todisplay(st_node), stnode_todisplay(entity)); - } - check_arithmetic_operation(dfw, st_arg1, FT_NONE); sttype_test_get(st_arg1, NULL, &entity, NULL); @@ -1441,6 +1430,12 @@ check_arithmetic_operation(dfwork_t *dfw, stnode_t *st_node, ftenum_t lhs_ftype) FtypeCanFunc can_func = NULL; sttype_test_get(st_node, &st_op, &st_arg1, &st_arg2); + resolve_unparsed(dfw, st_arg1); + + /* On the LHS we require a field-like value as the first term. */ + if (lhs_ftype == FT_NONE && node_is_constant(st_arg1)) { + FAIL(dfw, "Constant arithmetic expression on the LHS is invalid."); + } switch (st_op) { case OP_UNARY_MINUS: @@ -1465,7 +1460,7 @@ check_arithmetic_operation(dfwork_t *dfw, stnode_t *st_node, ftenum_t lhs_ftype) } - ftype1 = check_arithmetic_entity(dfw, can_func, st_op, st_node, st_arg1, FT_NONE); + ftype1 = check_arithmetic_entity(dfw, can_func, st_op, st_node, st_arg1, lhs_ftype); ftype2 = check_arithmetic_entity(dfw, can_func, st_op, st_node, st_arg2, ftype1); if (!compatible_ftypes(ftype1, ftype2)) { diff --git a/test/suite_dfilter/group_syntax.py b/test/suite_dfilter/group_syntax.py index 8d65ddbb87..3dfa84141b 100644 --- a/test/suite_dfilter/group_syntax.py +++ b/test/suite_dfilter/group_syntax.py @@ -182,7 +182,7 @@ class case_unary_minus(unittest.TestCase): checkDFilterCount(dfilter, 0) def test_unary_3(self, checkDFilterFail): - error = 'Left side of "==" expression must be a field or function' + error = 'Constant arithmetic expression on the LHS is invalid' dfilter = "-2 == tcp.dstport" checkDFilterFail(dfilter, error) @@ -194,6 +194,15 @@ class case_arithmetic(unittest.TestCase): dfilter = "udp.dstport == udp.srcport + 1" checkDFilterCount(dfilter, 2) + def test_add_2(self, checkDFilterCount): + dfilter = "udp.dstport == 66 + 1" + checkDFilterCount(dfilter, 2) + + def test_add_3(self, checkDFilterFail): + error = 'Constant arithmetic expression on the LHS is invalid' + dfilter = "2 + 3 == frame.number" + checkDFilterFail(dfilter, error) + def test_sub_1(self, checkDFilterCount): dfilter = "udp.srcport == udp.dstport - 1" checkDFilterCount(dfilter, 2)