diff options
Diffstat (limited to 'epan/dfilter/semcheck.c')
-rw-r--r-- | epan/dfilter/semcheck.c | 60 |
1 files changed, 57 insertions, 3 deletions
diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c index 1d86b1b25b..524accc2aa 100644 --- a/epan/dfilter/semcheck.c +++ b/epan/dfilter/semcheck.c @@ -27,6 +27,7 @@ #include "syntax-tree.h" #include "sttype-range.h" #include "sttype-test.h" +#include "sttype-set.h" #include "sttype-function.h" #include <epan/exceptions.h> @@ -430,6 +431,7 @@ check_exists(dfwork_t *dfw, stnode_t *st_arg1) case STTYPE_TEST: case STTYPE_INTEGER: case STTYPE_FVALUE: + case STTYPE_SET: case STTYPE_NUM_TYPES: g_assert_not_reached(); } @@ -615,7 +617,11 @@ check_relation_LHS_FIELD(dfwork_t *dfw, const char *relation_string, hfinfo1 = (header_field_info*)stnode_data(st_arg1); ftype1 = hfinfo1->type; - DebugLog((" 5 check_relation_LHS_FIELD(%s)\n", relation_string)); + if (stnode_type_id(st_node) == STTYPE_TEST) { + DebugLog((" 5 check_relation_LHS_FIELD(%s)\n", relation_string)); + } else { + DebugLog((" 6 check_relation_LHS_FIELD(%s)\n", relation_string)); + } if (!can_func(ftype1)) { dfilter_fail(dfw, "%s (type=%s) cannot participate in '%s' comparison.", @@ -674,7 +680,11 @@ check_relation_LHS_FIELD(dfwork_t *dfw, const char *relation_string, } new_st = stnode_new(STTYPE_FVALUE, fvalue); - sttype_test_set2_args(st_node, st_arg1, new_st); + if (stnode_type_id(st_node) == STTYPE_TEST) { + sttype_test_set2_args(st_node, st_arg1, new_st); + } else { + sttype_set_replace_element(st_node, st_arg2, new_st); + } stnode_free(st_arg2); } else if (type2 == STTYPE_RANGE) { @@ -712,6 +722,27 @@ check_relation_LHS_FIELD(dfwork_t *dfw, const char *relation_string, check_function(dfw, st_arg2); } + else if (type2 == STTYPE_SET) { + GSList *nodelist; + /* A set should only ever appear on RHS of 'in' operation */ + if (strcmp(relation_string, "in") != 0) { + g_assert_not_reached(); + } + /* Attempt to interpret one element of the set at a time */ + nodelist = (GSList*)stnode_data(st_arg2); + while (nodelist) { + stnode_t *node = (stnode_t*)nodelist->data; + /* Don't let a range on the RHS affect the LHS field. */ + if (stnode_type_id(node) == STTYPE_RANGE) { + dfilter_fail(dfw, "A range may not appear inside a set."); + THROW(TypeError); + break; + } + check_relation_LHS_FIELD(dfw, "==", can_func, + allow_partial_value, st_arg2, st_arg1, node); + nodelist = g_slist_next(nodelist); + } + } else { g_assert_not_reached(); } @@ -801,6 +832,10 @@ check_relation_LHS_STRING(dfwork_t *dfw, const char* relation_string, sttype_test_set2_args(st_node, new_st, st_arg2); stnode_free(st_arg1); } + else if (type2 == STTYPE_SET) { + dfilter_fail(dfw, "Only a field may be tested for membership in a set."); + THROW(TypeError); + } else { g_assert_not_reached(); } @@ -890,6 +925,10 @@ check_relation_LHS_UNPARSED(dfwork_t *dfw, const char* relation_string, sttype_test_set2_args(st_node, new_st, st_arg2); stnode_free(st_arg1); } + else if (type2 == STTYPE_SET) { + dfilter_fail(dfw, "Only a field may be tested for membership in a set."); + THROW(TypeError); + } else { g_assert_not_reached(); } @@ -1042,6 +1081,10 @@ check_relation_LHS_RANGE(dfwork_t *dfw, const char *relation_string, check_function(dfw, st_arg2); } + else if (type2 == STTYPE_SET) { + dfilter_fail(dfw, "Only a field may be tested for membership in a set."); + THROW(TypeError); + } else { g_assert_not_reached(); } @@ -1192,6 +1235,10 @@ check_relation_LHS_FUNCTION(dfwork_t *dfw, const char *relation_string, check_function(dfw, st_arg2); } + else if (type2 == STTYPE_SET) { + dfilter_fail(dfw, "Only a field may be tested for membership in a set."); + THROW(TypeError); + } else { g_assert_not_reached(); } @@ -1252,6 +1299,7 @@ header_field_info *hfinfo; case STTYPE_TEST: case STTYPE_INTEGER: case STTYPE_FVALUE: + case STTYPE_SET: default: g_assert_not_reached(); } @@ -1331,7 +1379,13 @@ check_test(dfwork_t *dfw, stnode_t *st_node, GPtrArray *deprecated) check_relation(dfw, "contains", TRUE, ftype_can_contains, st_node, st_arg1, st_arg2); break; case TEST_OP_MATCHES: - check_relation(dfw, "matches", TRUE, ftype_can_matches, st_node, st_arg1, st_arg2); break; + check_relation(dfw, "matches", TRUE, ftype_can_matches, st_node, st_arg1, st_arg2); + break; + case TEST_OP_IN: + /* Use the ftype_can_eq as the items in the set are evaluated using the + * semantics of equality. */ + check_relation(dfw, "in", FALSE, ftype_can_eq, st_node, st_arg1, st_arg2); + break; default: g_assert_not_reached(); |