aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dfilter
diff options
context:
space:
mode:
authorJoão Valverde <j@v6e.pt>2022-04-01 13:32:16 +0100
committerJoão Valverde <j@v6e.pt>2022-04-01 14:33:38 +0100
commit67e5e5c3ab8131fc58d69dda28dca71b676ed200 (patch)
tree12958c4eb3f4b0aa361f9561bc4a326b10d74430 /epan/dfilter
parent856cd96bb3b7140c8dbba61a4769c4cfaad424aa (diff)
dfilter: Fix arithmetic expressions on the LHS
Filter: _ws.ftypes.framenum % 3 == 0 Instructions: 00000 READ_TREE _ws.ftypes.framenum -> reg#0 00001 IF_FALSE_GOTO 4 00002 MODULO reg#0 % 3 <FT_FRAMENUM> -> reg#1 00003 ANY_EQ reg#1 == 0 <FT_FRAMENUM> 00004 RETURN
Diffstat (limited to 'epan/dfilter')
-rw-r--r--epan/dfilter/semcheck.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c
index 8132663b06..2fa0f0f27e 100644
--- a/epan/dfilter/semcheck.c
+++ b/epan/dfilter/semcheck.c
@@ -149,6 +149,20 @@ compatible_ftypes(ftenum_t a, ftenum_t b)
return FALSE;
}
+static gboolean
+node_is_constant(stnode_t *node)
+{
+ switch (stnode_type_id(node)) {
+ case STTYPE_CHARCONST:
+ case STTYPE_STRING:
+ case STTYPE_LITERAL:
+ return TRUE;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
/* Gets an fvalue from a string, and sets the error message on failure. */
WS_RETNONNULL
static fvalue_t*
@@ -999,30 +1013,37 @@ check_relation_LHS_BITWISE(dfwork_t *dfw, test_op_t st_op _U_,
static void
check_relation_LHS_ARITHMETIC(dfwork_t *dfw, test_op_t st_op _U_,
FtypeCanFunc can_func _U_, gboolean allow_partial_value,
- stnode_t *st_node _U_,
- stnode_t *st_arg1, stnode_t *st_arg2)
+ stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
{
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);
entity_type = stnode_type_id(entity);
if (entity_type == STTYPE_FIELD || entity_type == STTYPE_REFERENCE) {
- check_arithmetic_operation(dfw, st_arg1, FT_NONE);
-
check_relation_LHS_FIELD(dfw, st_op, can_func, allow_partial_value, st_node, entity, st_arg2);
}
else if (entity_type == STTYPE_FUNCTION) {
- check_arithmetic_operation(dfw, st_arg1, FT_NONE);
-
check_relation_LHS_FUNCTION(dfw, st_op, can_func, allow_partial_value, st_node, entity, st_arg2);
}
else {
- FAIL(dfw, "Left side of %s expression must be a field or function, not %s.",
- stnode_todisplay(st_node), stnode_todisplay(entity));
+ ws_assert_not_reached();
}
}
@@ -1347,6 +1368,10 @@ check_arithmetic_entity(dfwork_t *dfw, FtypeCanFunc can_func, test_op_t st_op,
sttype_id_t type;
ftenum_t ftype;
+ /* lhs_ftype variable determines the type for this entity. If LHS type
+ * is none we must have been passed an entity with a definite type
+ * (field, function, etc). */
+
resolve_unparsed(dfw, st_arg);
type = stnode_type_id(st_arg);
@@ -1440,8 +1465,8 @@ 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, lhs_ftype);
- ftype2 = check_arithmetic_entity(dfw, can_func, st_op, st_node, st_arg2, lhs_ftype);
+ ftype1 = check_arithmetic_entity(dfw, can_func, st_op, st_node, st_arg1, FT_NONE);
+ ftype2 = check_arithmetic_entity(dfw, can_func, st_op, st_node, st_arg2, ftype1);
if (!compatible_ftypes(ftype1, ftype2)) {
FAIL(dfw, "%s and %s are not type compatible.",