diff options
author | João Valverde <j@v6e.pt> | 2022-04-04 11:33:38 +0100 |
---|---|---|
committer | João Valverde <j@v6e.pt> | 2022-04-05 12:04:37 +0100 |
commit | 20afbd46ecd4ffe954ea95240bf8862358fd7066 (patch) | |
tree | ffe6af1721e0e88fd18c74e45cf65520fef44c65 /epan/dfilter | |
parent | fb08c4b4a809411d0da8397a5de7ff2923e103db (diff) |
dfilter: Remove existence test syntax tree nodes
After some experimentation I don't think these two existence tests
belong in the grammar, it's an implementation detail and removing it
might avoid some artificial constraints.
Diffstat (limited to 'epan/dfilter')
-rw-r--r-- | epan/dfilter/gencode.c | 84 | ||||
-rw-r--r-- | epan/dfilter/grammar.lemon | 6 | ||||
-rw-r--r-- | epan/dfilter/semcheck.c | 17 | ||||
-rw-r--r-- | epan/dfilter/sttype-test.c | 14 | ||||
-rw-r--r-- | epan/dfilter/syntax-tree.h | 2 |
5 files changed, 55 insertions, 68 deletions
diff --git a/epan/dfilter/gencode.c b/epan/dfilter/gencode.c index 2674417a10..d68ef697e2 100644 --- a/epan/dfilter/gencode.c +++ b/epan/dfilter/gencode.c @@ -430,6 +430,47 @@ gen_entity(dfwork_t *dfw, stnode_t *st_arg, GSList **jumps_ptr) return val; } +static void +gen_exists(dfwork_t *dfw, stnode_t *st_node) +{ + dfvm_insn_t *insn; + header_field_info *hfinfo; + + hfinfo = stnode_data(st_node); + + /* Rewind to find the first field of this name. */ + while (hfinfo->same_name_prev_id != -1) { + hfinfo = proto_registrar_get_nth(hfinfo->same_name_prev_id); + } + insn = dfvm_insn_new(CHECK_EXISTS); + insn->arg1 = dfvm_value_new_hfinfo(hfinfo); + dfw_append_insn(dfw, insn); + + /* Record the FIELD_ID in hash of interesting fields. */ + while (hfinfo) { + g_hash_table_insert(dfw->interesting_fields, + GINT_TO_POINTER(hfinfo->id), + GUINT_TO_POINTER(TRUE)); + hfinfo = hfinfo->same_name_next; + } +} + +static void +gen_notzero(dfwork_t *dfw, stnode_t *st_node) +{ + dfvm_insn_t *insn; + dfvm_value_t *val1; + GSList *jumps = NULL; + + val1 = gen_arithmetic(dfw, st_node, &jumps); + insn = dfvm_insn_new(ALL_ZERO); + insn->arg1 = dfvm_value_ref(val1); + dfw_append_insn(dfw, insn); + insn = dfvm_insn_new(NOT); + dfw_append_insn(dfw, insn); + g_slist_foreach(jumps, fixup_jumps, dfw); + g_slist_free(jumps); +} static void gen_test(dfwork_t *dfw, stnode_t *st_node) @@ -437,10 +478,8 @@ gen_test(dfwork_t *dfw, stnode_t *st_node) test_op_t st_op; stnode_t *st_arg1, *st_arg2; dfvm_insn_t *insn; - dfvm_value_t *jmp, *val1; - GSList *jumps = NULL; + dfvm_value_t *jmp; - header_field_info *hfinfo; sttype_test_get(st_node, &st_op, &st_arg1, &st_arg2); @@ -449,39 +488,6 @@ gen_test(dfwork_t *dfw, stnode_t *st_node) ws_assert_not_reached(); break; - case TEST_OP_EXISTS: - hfinfo = stnode_data(st_arg1); - - /* Rewind to find the first field of this name. */ - while (hfinfo->same_name_prev_id != -1) { - hfinfo = proto_registrar_get_nth(hfinfo->same_name_prev_id); - } - insn = dfvm_insn_new(CHECK_EXISTS); - insn->arg1 = dfvm_value_new_hfinfo(hfinfo); - dfw_append_insn(dfw, insn); - - /* Record the FIELD_ID in hash of interesting fields. */ - while (hfinfo) { - g_hash_table_insert(dfw->interesting_fields, - GINT_TO_POINTER(hfinfo->id), - GUINT_TO_POINTER(TRUE)); - hfinfo = hfinfo->same_name_next; - } - - break; - - case TEST_OP_NOTZERO: - val1 = gen_entity(dfw, st_arg1, &jumps); - insn = dfvm_insn_new(ALL_ZERO); - insn->arg1 = dfvm_value_ref(val1); - dfw_append_insn(dfw, insn); - insn = dfvm_insn_new(NOT); - dfw_append_insn(dfw, insn); - g_slist_foreach(jumps, fixup_jumps, dfw); - g_slist_free(jumps); - jumps = NULL; - break; - case TEST_OP_NOT: gencode(dfw, st_arg1); insn = dfvm_insn_new(NOT); @@ -575,6 +581,12 @@ gencode(dfwork_t *dfw, stnode_t *st_node) case STTYPE_TEST: gen_test(dfw, st_node); break; + case STTYPE_FIELD: + gen_exists(dfw, st_node); + break; + case STTYPE_ARITHMETIC: + gen_notzero(dfw, st_node); + break; default: ws_assert_not_reached(); } diff --git a/epan/dfilter/grammar.lemon b/epan/dfilter/grammar.lemon index 78646f3dcc..7f6ac3857a 100644 --- a/epan/dfilter/grammar.lemon +++ b/epan/dfilter/grammar.lemon @@ -123,14 +123,12 @@ logical_test(T) ::= TEST_NOT(L) expr(E). logical_test(T) ::= entity(E). { - T = new_test(dfw, TEST_OP_EXISTS, NULL); - sttype_test_set1_args(T, E); + T = E; } logical_test(T) ::= arithmetic_term(E). { - T = new_test(dfw, TEST_OP_NOTZERO, NULL); - sttype_test_set1_args(T, E); + T = E; } diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c index ff176e179c..6798e9d457 100644 --- a/epan/dfilter/semcheck.c +++ b/epan/dfilter/semcheck.c @@ -470,6 +470,7 @@ check_exists(dfwork_t *dfw, stnode_t *st_arg1) switch (stnode_type_id(st_arg1)) { case STTYPE_FIELD: + case STTYPE_ARITHMETIC: /* This is OK */ break; case STTYPE_REFERENCE: @@ -477,7 +478,6 @@ check_exists(dfwork_t *dfw, stnode_t *st_arg1) case STTYPE_UNPARSED: case STTYPE_LITERAL: case STTYPE_CHARCONST: - case STTYPE_ARITHMETIC: FAIL(dfw, "%s is neither a field nor a protocol name.", stnode_todisplay(st_arg1)); break; @@ -1136,14 +1136,6 @@ check_test(dfwork_t *dfw, stnode_t *st_node) ws_assert_not_reached(); break; - case TEST_OP_EXISTS: - check_exists(dfw, st_arg1); - break; - - case TEST_OP_NOTZERO: - check_arithmetic_operation(dfw, st_arg1, FT_NONE); - break; - case TEST_OP_NOT: semcheck(dfw, st_arg1); break; @@ -1316,14 +1308,15 @@ semcheck(dfwork_t *dfw, stnode_t *st_node) { LOG_NODE(st_node); - /* The parser assures that the top-most syntax-tree - * node will be a TEST node, no matter what. So assert that. */ switch (stnode_type_id(st_node)) { case STTYPE_TEST: check_test(dfw, st_node); break; + case STTYPE_ARITHMETIC: + check_arithmetic_operation(dfw, st_node, FT_NONE); + break; default: - ws_assert_not_reached(); + check_exists(dfw, st_node); } } diff --git a/epan/dfilter/sttype-test.c b/epan/dfilter/sttype-test.c index 9e08de8374..13c0040ee3 100644 --- a/epan/dfilter/sttype-test.c +++ b/epan/dfilter/sttype-test.c @@ -70,9 +70,6 @@ test_todisplay(test_op_t op) const char *s = "<notset>"; switch(op) { - case TEST_OP_EXISTS: - s = "<exists>"; - break; case TEST_OP_NOT: s = "!"; break; @@ -125,9 +122,6 @@ test_todisplay(test_op_t op) case OP_MODULO: s = "%"; break; - case TEST_OP_NOTZERO: - s = "<notzero>"; - break; case TEST_OP_CONTAINS: s = "contains"; break; @@ -150,9 +144,6 @@ test_todebug(test_op_t op) const char *s = "<notset>"; switch(op) { - case TEST_OP_EXISTS: - s = "TEST_EXISTS"; - break; case TEST_OP_NOT: s = "TEST_NOT"; break; @@ -207,9 +198,6 @@ test_todebug(test_op_t op) case OP_MODULO: s = "OP_MODULO"; break; - case TEST_OP_NOTZERO: - s = "TEST_NOTZERO"; - break; case TEST_OP_CONTAINS: s = "TEST_CONTAINS"; break; @@ -246,9 +234,7 @@ num_operands(test_op_t op) switch(op) { case TEST_OP_UNINITIALIZED: break; - case TEST_OP_EXISTS: case TEST_OP_NOT: - case TEST_OP_NOTZERO: case OP_UNARY_MINUS: return 1; case TEST_OP_AND: diff --git a/epan/dfilter/syntax-tree.h b/epan/dfilter/syntax-tree.h index 3fa27841d1..d7bdce55d5 100644 --- a/epan/dfilter/syntax-tree.h +++ b/epan/dfilter/syntax-tree.h @@ -39,7 +39,6 @@ typedef enum { typedef enum { TEST_OP_UNINITIALIZED, - TEST_OP_EXISTS, TEST_OP_NOT, TEST_OP_AND, TEST_OP_OR, @@ -58,7 +57,6 @@ typedef enum { OP_MULTIPLY, OP_DIVIDE, OP_MODULO, - TEST_OP_NOTZERO, TEST_OP_CONTAINS, TEST_OP_MATCHES, TEST_OP_IN |