diff options
author | João Valverde <j@v6e.pt> | 2022-12-27 23:23:00 +0000 |
---|---|---|
committer | João Valverde <j@v6e.pt> | 2022-12-30 18:46:22 +0000 |
commit | 6bdc85e37f510ffc9afee2c93b80675c42fb066e (patch) | |
tree | f446b13070d67991aed9ca9c1a6b8aabd76b012d | |
parent | a17fb20550379640ba0c43c99f2a13107efa27c4 (diff) |
dfilter: Reject constant expressions
Constant logical expressions are tautologies and almost certainly
user error. Reject them as invalid.
Most of them were already rejected with insufficient type information
but some corner cases were still valid.
Before:
Filter: ${frame.number} == 3
Syntax tree:
0 TEST_ANY_EQ:
1 REFERENCE(frame.number <FT_UINT32>)
1 FVALUE(3 <FT_UINT32>)
Instructions:
00000 READ_REFERENCE ${frame.number <FT_UINT32>} -> reg#0
00001 IF_FALSE_GOTO 3
00002 ANY_EQ reg#0 == 3 <FT_UINT32>
00003 RETURN
After:
Filter: ${frame.number} == 3
dftest: Constant expression is invalid.
${frame.number} == 3
^~~~~~~~~~~~~~~~~~~~
-rw-r--r-- | epan/dfilter/dfilter-int.h | 1 | ||||
-rw-r--r-- | epan/dfilter/dfunctions.c | 13 | ||||
-rw-r--r-- | epan/dfilter/semcheck.c | 39 |
3 files changed, 43 insertions, 10 deletions
diff --git a/epan/dfilter/dfilter-int.h b/epan/dfilter/dfilter-int.h index de546d7cda..0fd1f0bbdc 100644 --- a/epan/dfilter/dfilter-int.h +++ b/epan/dfilter/dfilter-int.h @@ -45,6 +45,7 @@ typedef struct { /* Syntax Tree stuff */ stnode_t *st_root; gboolean parse_failure; + unsigned field_count; df_error_t error; GPtrArray *insns; GHashTable *loaded_fields; diff --git a/epan/dfilter/dfunctions.c b/epan/dfilter/dfunctions.c index 1ef91e78c0..0dc23c9438 100644 --- a/epan/dfilter/dfunctions.c +++ b/epan/dfilter/dfunctions.c @@ -255,6 +255,7 @@ ul_semcheck_is_field_string(dfwork_t *dfw, const char *func_name, ftenum_t lhs_f stnode_t *st_node = param_list->data; if (stnode_type_id(st_node) == STTYPE_FIELD) { + dfw->field_count++; hfinfo = sttype_field_hfinfo(st_node); if (IS_FT_STRING(hfinfo->type)) { return FT_STRING; @@ -270,8 +271,10 @@ ul_semcheck_is_field(dfwork_t *dfw, const char *func_name, ftenum_t lhs_ftype _U ws_assert(g_slist_length(param_list) == 1); stnode_t *st_node = param_list->data; - if (stnode_type_id(st_node) == STTYPE_FIELD) + if (stnode_type_id(st_node) == STTYPE_FIELD) { + dfw->field_count++; return FT_UINT32; + } FAIL(dfw, st_node, "Only fields can be used as parameter for %s()", func_name); } @@ -286,6 +289,7 @@ ul_semcheck_string_param(dfwork_t *dfw, const char *func_name, ftenum_t lhs_ftyp stnode_t *st_node = param_list->data; if (stnode_type_id(st_node) == STTYPE_FIELD) { + dfw->field_count++; hfinfo = sttype_field_hfinfo(st_node); switch (hfinfo->type) { case FT_UINT8: @@ -375,7 +379,11 @@ ul_semcheck_compare(dfwork_t *dfw, const char *func_name, ftenum_t lhs_ftype, else if (type == STTYPE_FUNCTION) { ft_arg = check_function(dfw, arg, ftype); } - else if (type == STTYPE_FIELD || type == STTYPE_REFERENCE) { + else if (type == STTYPE_FIELD) { + dfw->field_count++; + ft_arg = sttype_field_ftenum(arg); + } + else if (type == STTYPE_REFERENCE) { ft_arg = sttype_field_ftenum(arg); } else { @@ -441,6 +449,7 @@ ul_semcheck_absolute_value(dfwork_t *dfw, const char *func_name, ftenum_t lhs_ft ftype = check_function(dfw, st_node, lhs_ftype); } else if (stnode_type_id(st_node) == STTYPE_FIELD) { + dfw->field_count++; ftype = sttype_field_ftenum(st_node); } else { diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c index a08cc6c7d5..abcac8c6e9 100644 --- a/epan/dfilter/semcheck.c +++ b/epan/dfilter/semcheck.c @@ -463,6 +463,7 @@ check_exists(dfwork_t *dfw, stnode_t *st_arg1) switch (stnode_type_id(st_arg1)) { case STTYPE_FIELD: /* This is OK */ + dfw->field_count++; break; case STTYPE_REFERENCE: case STTYPE_STRING: @@ -503,6 +504,7 @@ check_slice(dfwork_t *dfw, stnode_t *st, ftenum_t lhs_ftype) ws_assert(entity1); if (stnode_type_id(entity1) == STTYPE_FIELD) { + dfw->field_count++; hfinfo1 = sttype_field_hfinfo(entity1); ftype1 = hfinfo1->type; @@ -606,19 +608,19 @@ check_relation_LHS_FIELD(dfwork_t *dfw, stnode_op_t st_op, LOG_NODE(st_node); - type2 = stnode_type_id(st_arg2); + if (stnode_type_id(st_arg1) == STTYPE_FIELD) + dfw->field_count++; - ws_assert(stnode_type_id(st_arg1) == STTYPE_FIELD || - stnode_type_id(st_arg1) == STTYPE_REFERENCE); hfinfo1 = sttype_field_hfinfo(st_arg1); ftype1 = sttype_field_ftenum(st_arg1); - if (!can_func(ftype1)) { FAIL(dfw, st_arg1, "%s (type=%s) cannot participate in %s comparison.", hfinfo1->abbrev, ftype_pretty_name(ftype1), stnode_todisplay(st_node)); } + type2 = stnode_type_id(st_arg2); + if (IS_FIELD_ENTITY(type2)) { ftype2 = sttype_field_ftenum(st_arg2); @@ -632,6 +634,9 @@ check_relation_LHS_FIELD(dfwork_t *dfw, stnode_op_t st_op, FAIL(dfw, st_arg2, "%s (type=%s) cannot participate in specified comparison.", stnode_todisplay(st_arg2), ftype_pretty_name(ftype2)); } + if (type2 == STTYPE_FIELD) { + dfw->field_count++; + } } else if (type2 == STTYPE_STRING || type2 == STTYPE_LITERAL) { /* Skip incompatible fields */ @@ -735,6 +740,9 @@ check_relation_LHS_FVALUE(dfwork_t *dfw, stnode_op_t st_op _U_, FAIL(dfw, st_arg2, "%s (type=%s) cannot participate in specified comparison.", stnode_todisplay(st_arg2), ftype_pretty_name(ftype2)); } + if (type2 == STTYPE_FIELD) { + dfw->field_count++; + } } else if (type2 == STTYPE_STRING || type2 == STTYPE_LITERAL || @@ -820,6 +828,9 @@ check_relation_LHS_SLICE(dfwork_t *dfw, stnode_op_t st_op, /* Convert entire field to bytes */ convert_to_bytes(st_arg2); } + if (type2 == STTYPE_FIELD) { + dfw->field_count++; + } } else if (type2 == STTYPE_STRING) { fvalue = dfilter_fvalue_from_string(dfw, FT_BYTES, st_arg2, NULL); @@ -918,6 +929,9 @@ check_relation_LHS_FUNCTION(dfwork_t *dfw, stnode_op_t st_op, FAIL(dfw, st_arg2, "%s (type=%s) cannot participate in specified comparison.", stnode_todisplay(st_arg2), ftype_pretty_name(ftype2)); } + if (type2 == STTYPE_FIELD) { + dfw->field_count++; + } } else if (type2 == STTYPE_STRING) { fvalue = dfilter_fvalue_from_string(dfw, ftype1, st_arg2, NULL); @@ -1024,6 +1038,9 @@ check_relation_LHS_ARITHMETIC(dfwork_t *dfw, stnode_op_t st_op, FAIL(dfw, st_arg2, "%s (type=%s) cannot participate in specified comparison.", stnode_todisplay(st_arg2), ftype_pretty_name(ftype2)); } + if (type2 == STTYPE_FIELD) { + dfw->field_count++; + } } else if (type2 == STTYPE_STRING) { fvalue = dfilter_fvalue_from_string(dfw, ftype1, st_arg2, NULL); @@ -1473,12 +1490,12 @@ check_arithmetic(dfwork_t *dfw, stnode_t *st_node, ftenum_t lhs_ftype) break; case STTYPE_FIELD: + dfw->field_count++; + /* fall-through */ case STTYPE_REFERENCE: - { - header_field_info *hfinfo = sttype_field_hfinfo(st_node); - ftype = hfinfo->type; + ftype = sttype_field_ftenum(st_node); break; - } + case STTYPE_FUNCTION: ftype = check_function(dfw, st_node, lhs_ftype); break; @@ -1511,6 +1528,8 @@ semcheck(dfwork_t *dfw, stnode_t *st_node) { LOG_NODE(st_node); + dfw->field_count = 0; + switch (stnode_type_id(st_node)) { case STTYPE_TEST: check_test(dfw, st_node); @@ -1522,6 +1541,10 @@ semcheck(dfwork_t *dfw, stnode_t *st_node) default: check_exists(dfw, st_node); } + + if (dfw->field_count == 0) { + FAIL(dfw, st_node, "Constant expression is invalid."); + } } |