aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dfilter/semcheck.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dfilter/semcheck.c')
-rw-r--r--epan/dfilter/semcheck.c60
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();