aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorJoão Valverde <j@v6e.pt>2022-02-22 21:55:05 +0000
committerA Wireshark GitLab Utility <gerald+gitlab-utility@wireshark.org>2022-03-05 11:10:54 +0000
commit6d520addd1f147bffca0402e05d1eb2152f66cd2 (patch)
tree73696f00fe14690e835ca89838a463996b38f24c /test
parent64d95a28086f2939072d68fb78676da6e8748d62 (diff)
dfilter: Add special syntax for literals and names
The syntax for protocols and some literals like numbers and bytes/addresses can be ambiguous. Some protocols can be parsed as a literal, for example the protocol "fc" (Fibre Channel) can be parsed as 0xFC. If a numeric protocol is registered that will also take precedence over any literal, according to the current rules, thereby breaking numerical comparisons to that number. The same for an hypothetical protocol named "true", etc. To allow the user to disambiguate this meaning introduce new syntax. Any value prefixed with ':' or enclosed in <,> will be treated as a literal value only. The value :fc or <fc> will always mean 0xFC, under any context. Never a protocol whose filter name is "fc". Likewise any value prefixed with a dot will always be parsed as an identifier (protocol or protocol field) in the language. Never any literal value parsed from the token "fc". This allows the user to be explicit about the meaning, and between the two explicit methods plus the ambiguous one it doesn't completely break any one meaning. The difference can be seen in the following two programs: Filter: frame == fc Constants: Instructions: 00000 READ_TREE frame -> reg#0 00001 IF-FALSE-GOTO 5 00002 READ_TREE fc -> reg#1 00003 IF-FALSE-GOTO 5 00004 ANY_EQ reg#0 == reg#1 00005 RETURN -------- Filter: frame == :fc Constants: 00000 PUT_FVALUE fc <FT_PROTOCOL> -> reg#1 Instructions: 00000 READ_TREE frame -> reg#0 00001 IF-FALSE-GOTO 3 00002 ANY_EQ reg#0 == reg#1 00003 RETURN The filter "frame == fc" is the same as "filter == .fc", according to the current heuristic, except the first form will try to parse it as a literal if the name does not correspond to any registered protocol. By treating a leading dot as a name in the language we necessarily disallow writing floats with a leading dot. We will also disallow writing with an ending dot when using unparsed values. This is a backward incompatibility but has the happy side effect of making the expression {1...2} unambiguous. This could either mean "1 .. .2" or "1. .. 2". If we require a leading and ending digit then the meaning is clear: 1.0..0.2 -> 1.0 .. 0.2 Fixes #17731.
Diffstat (limited to 'test')
-rw-r--r--test/suite_dfilter/group_membership.py6
-rw-r--r--test/suite_dfilter/group_syntax.py12
2 files changed, 16 insertions, 2 deletions
diff --git a/test/suite_dfilter/group_membership.py b/test/suite_dfilter/group_membership.py
index 4f9b315f0d..20072e2db1 100644
--- a/test/suite_dfilter/group_membership.py
+++ b/test/suite_dfilter/group_membership.py
@@ -72,10 +72,12 @@ class case_membership(unittest.TestCase):
dfilter = 'ip.addr in { 10.0.0.5 .. 10.0.0.9 , 10.0.0.1..10.0.0.1 }'
checkDFilterCount(dfilter, 1)
- def test_membership_9_range_weird_float(self, checkDFilterCount):
+ def test_membership_9_range_invalid_float(self, checkDFilterFail):
# expression should be parsed as "0.1 .. .7"
+ # .7 is the identifier (protocol) named "7"
dfilter = 'frame.time_delta in {0.1...7}'
- checkDFilterCount(dfilter, 0)
+ error = 'not a valid protocol or protocol field'
+ checkDFilterFail(dfilter, error)
def test_membership_10_bad_lhs_number(self, checkDFilterFail):
dfilter = '123 in {ip}'
diff --git a/test/suite_dfilter/group_syntax.py b/test/suite_dfilter/group_syntax.py
index 171cd330a5..b5c6236931 100644
--- a/test/suite_dfilter/group_syntax.py
+++ b/test/suite_dfilter/group_syntax.py
@@ -135,3 +135,15 @@ class case_equality(unittest.TestCase):
def test_all_ne_1(self, checkDFilterCount):
dfilter = "udp.port != 5060"
checkDFilterCount(dfilter, 1)
+
+ def test_root_1(self, checkDFilterCount):
+ dfilter = "udp.srcport == .udp.dstport"
+ checkDFilterCount(dfilter, 2)
+
+ def test_literal_1(self, checkDFilterCount):
+ dfilter = "udp.port == :5070"
+ checkDFilterCount(dfilter, 3)
+
+ def test_literal_2(self, checkDFilterCount):
+ dfilter = "udp contains <ce:13>"
+ checkDFilterCount(dfilter, 1)