diff options
author | João Valverde <j@v6e.pt> | 2023-10-31 13:27:23 +0000 |
---|---|---|
committer | João Valverde <j@v6e.pt> | 2023-10-31 14:54:19 +0000 |
commit | 9b62ec029eb6af5301088c6d8b65f8cf9cf83021 (patch) | |
tree | 2723269dcd79c30d2e3ae46b9facf39bf3b7f814 | |
parent | 1dd58a0559ed009f473f0582d26c1c0bbf194563 (diff) |
dfilter: Fix slices with byte references
Before:
Filter:
frame[:2] == $@frame[:2]
Error: Range is not supported for entity @frame <FT_BYTES>
frame[:2] == $@frame[:2]
^~~~~~~
After:
Filter:
frame[:2] == $@frame[:2]
Instructions:
0000 READ_TREE frame -> R0
0001 IF_FALSE_GOTO 7
0002 SLICE R0[0:2] -> R1
0003 READ_REFERENCE ${@frame} -> R2
0004 IF_FALSE_GOTO 7
0005 SLICE R2[0:2] -> R3
0006 ANY_EQ R1 == R3
0007 RETURN
-rw-r--r-- | epan/dfilter/semcheck.c | 64 | ||||
-rw-r--r-- | test/suite_dfilter/group_syntax.py | 10 |
2 files changed, 54 insertions, 20 deletions
diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c index 64ac703993..3c538d56f2 100644 --- a/epan/dfilter/semcheck.c +++ b/epan/dfilter/semcheck.c @@ -779,34 +779,58 @@ check_slice(dfwork_t *dfw, stnode_t *st, ftenum_t logical_ftype) { stnode_t *entity1; header_field_info *hfinfo1; - ftenum_t ftype1; + sttype_id_t sttype1; + ftenum_t ftype1 = FT_NONE; LOG_NODE(st); entity1 = sttype_slice_entity(st); ws_assert(entity1); + sttype1 = stnode_type_id(entity1); - if (stnode_type_id(entity1) == STTYPE_FIELD) { - dfw->field_count++; - hfinfo1 = sttype_field_hfinfo(entity1); - ftype1 = sttype_field_ftenum(entity1); + switch (sttype1) { + case STTYPE_FIELD: + dfw->field_count++; + /* fall-through */ + case STTYPE_REFERENCE: + hfinfo1 = sttype_field_hfinfo(entity1); + ftype1 = sttype_field_ftenum(entity1); - if (!ftype_can_slice(ftype1)) { - FAIL(dfw, entity1, "\"%s\" is a %s and cannot be sliced into a sequence of bytes.", - hfinfo1->abbrev, ftype_pretty_name(ftype1)); - } - } else if (stnode_type_id(entity1) == STTYPE_FUNCTION) { - ftype1 = check_function(dfw, entity1, logical_ftype); + if (!ftype_can_slice(ftype1)) { + FAIL(dfw, entity1, "\"%s\" is a %s and cannot be sliced into a sequence of bytes.", + hfinfo1->abbrev, ftype_pretty_name(ftype1)); + } + break; + + case STTYPE_FUNCTION: + ftype1 = check_function(dfw, entity1, logical_ftype); + + if (!ftype_can_slice(ftype1)) { + FAIL(dfw, entity1, "Return value of function \"%s\" is a %s and cannot be converted into a sequence of bytes.", + sttype_function_name(entity1), ftype_pretty_name(ftype1)); + } + break; + + case STTYPE_SLICE: + ftype1 = check_slice(dfw, entity1, logical_ftype); + break; + + case STTYPE_LITERAL: + case STTYPE_STRING: + case STTYPE_CHARCONST: + case STTYPE_NUMBER: + FAIL(dfw, entity1, "Range is not supported for entity %s", + stnode_todisplay(entity1)); + + case STTYPE_UNINITIALIZED: + case STTYPE_NUM_TYPES: + case STTYPE_PCRE: + case STTYPE_FVALUE: + case STTYPE_TEST: + case STTYPE_ARITHMETIC: + case STTYPE_SET: + ASSERT_STTYPE_NOT_REACHED(sttype1); - if (!ftype_can_slice(ftype1)) { - FAIL(dfw, entity1, "Return value of function \"%s\" is a %s and cannot be converted into a sequence of bytes.", - sttype_function_name(entity1), ftype_pretty_name(ftype1)); - } - } else if (stnode_type_id(entity1) == STTYPE_SLICE) { - ftype1 = check_slice(dfw, entity1, logical_ftype); - } else { - FAIL(dfw, entity1, "Range is not supported for entity %s", - stnode_todisplay(entity1)); } return FT_IS_STRING(ftype1) ? FT_STRING : FT_BYTES; diff --git a/test/suite_dfilter/group_syntax.py b/test/suite_dfilter/group_syntax.py index 89fc5596c1..24e239605c 100644 --- a/test/suite_dfilter/group_syntax.py +++ b/test/suite_dfilter/group_syntax.py @@ -353,6 +353,16 @@ class TestDfilterFieldReference: # select frame 1, expect 1 frames out of 2. checkDFilterCountWithSelectedFrame(dfilter, 1, 1) + def test_ref_5(self, checkDFilterCountWithSelectedFrame): + dfilter = 'frame[52-54] == ${@ip.src}[0-2]' + # select frame 1, expect 1 frames out of 2. + checkDFilterCountWithSelectedFrame(dfilter, 1, 1) + + def test_ref_6(self, checkDFilterCountWithSelectedFrame): + dfilter = 'frame[52-54] == $@ip.src[0-2]' + # select frame 1, expect 1 frames out of 2. + checkDFilterCountWithSelectedFrame(dfilter, 1, 1) + class TestDfilterLayer: trace_file = "ipoipoip.pcap" |