- ws_assert does not work, because _ASSERT_ENABLED is false and gets optimized
- add _U_ to unused variables because of compile flag /W3
- local variables need suppression of warning 4189
Constant logical expressions are tautologies and almost certainly
user error. Reject them as invalid.
Most of them were already rejected with insufficient type information
but some corner cases were still valid.
Before:
Filter: ${frame.number} == 3
Syntax tree:
0 TEST_ANY_EQ:
1 REFERENCE(frame.number <FT_UINT32>)
1 FVALUE(3 <FT_UINT32>)
Instructions:
00000 READ_REFERENCE ${frame.number <FT_UINT32>} -> reg#0
00001 IF_FALSE_GOTO 3
00002 ANY_EQ reg#0 == 3 <FT_UINT32>
00003 RETURN
After:
Filter: ${frame.number} == 3
dftest: Constant expression is invalid.
${frame.number} == 3
^~~~~~~~~~~~~~~~~~~~
The strategy here is to delay resolving literals to values until
we have looked at the entire argument list.
Also we will try to commute the relation in a comparison if
we do not have a type for the return value of the function,
like any other constant.
Before:
Filter: max(1,_ws.ftypes.int8) == 1
dftest: Argument '1' is not valid for max()
max(1,_ws.ftypes.int8) == 1
^
After:
Filter: max(1,_ws.ftypes.int8) == 1
Syntax tree:
0 TEST_ANY_EQ:
1 FUNCTION(max#2):
2 FVALUE(1 <FT_INT8>)
2 FIELD(_ws.ftypes.int8 <FT_INT8>)
1 FVALUE(1 <FT_INT8>)
Instructions:
00000 STACK_PUSH 1 <FT_INT8>
00001 READ_TREE _ws.ftypes.int8 <FT_INT8> -> reg#1
00002 IF_FALSE_GOTO 3
00003 STACK_PUSH reg#1
00004 CALL_FUNCTION max(reg#1, 1 <FT_INT8>) -> reg#0
00005 STACK_POP 2
00006 IF_FALSE_GOTO 8
00007 ANY_EQ reg#0 == 1 <FT_INT8>
00008 RETURN
Filter: max(1,_ws.ftypes.int8) == 1
** (dftest:64938) 01:43:25.950180 [DFilter ERROR] epan/dfilter/sttype-field.c:117 -- sttype_field_ftenum(): Magic num is 0x5cf30031, but should be 0xfc2002cf
This parameter was introduced as a safeguard for bugs
that generate an unbounded string but its utility for
that purpose is doubtful and the way it is being used
creates problems with invalid truncation of UTF-8
strings.
Rename wmem_strbuf_sized_new() with a better name.
Return an struct containing error information. This simplifies
the interface to more easily provide richer diagnostics in the future.
Add an error code besides a human-readable error string to allow
checking programmatically for errors in a robust manner. Currently
there is only a generic error code, it is expected to increase
in the future.
Move error location information to the struct. Change callers and
implementation to use the new interface.
Passing a literal value to abs() on the LHS segfaults, because it
is incorrectly assumed to be a valid field.
We need to check if we actually have a field. While at it improve
the diagnostic of literals.
Allow checking if a slice exists. The result is true if the
slice has length greater than zero.
The len() function is implemented as a DFVM instruction instead.
The semantics are the same.
This removes unparsed name resolution during the semantic
check because it feels like a hack to work around limitations
in the language syntax, that should be solved at the lexical
level instead.
We were interpreting unparsed differently on the LHS and RHS.
Now an unparsed value is always a field if it matches a
registered field name (this matches the implementation in 3.6
and before).
This requires tightening a bit the allowed filter names for
protocols to avoid some common and potentially weird conflicting
cases.
Incidentally this extends set grammar to accept all entities.
That is experimental and may be reverted in the future.
This adds support for using the layers filter
with field references.
Before:
$ dftest 'ip.src != ${ip.src#2}'
dftest: invalid character in macro name
After:
$ dftest 'ip.src != ${ip.src#2}'
Filter: ip.src != ${ip.src#2}
Syntax tree:
0 TEST_ALL_NE:
1 FIELD(ip.src <FT_IPv4>)
1 REFERENCE(ip.src#[2:1] <FT_IPv4>)
Instructions:
00000 READ_TREE ip.src <FT_IPv4> -> reg#0
00001 IF_FALSE_GOTO 5
00002 READ_REFERENCE_R ${ip.src <FT_IPv4>} #[2:1] -> reg#1
00003 IF_FALSE_GOTO 5
00004 ALL_NE reg#0 != reg#1
00005 RETURN
This requires adding another level of complexity to references.
When loading references we need to copy the 'proto_layer_num'
and add the logic to filter on that.
The "layer" sttype is removed and replace by a new
field sttype with support for a range. This is a nice
cleanup for the semantic check and general simplification.
The grammar is better too with this design.
Range sttype is renamed to slice for clarity.
This allows writing moderately complex expressions, for example
a float epsilon test (#16483):
Filter: {abs(_ws.ftypes.double - 1) / max(abs(_ws.ftypes.double), abs(1))} < 0.01
Syntax tree:
0 TEST_LT:
1 OP_DIVIDE:
2 FUNCTION(abs#1):
3 OP_SUBTRACT:
4 FIELD(_ws.ftypes.double)
4 FVALUE(1 <FT_DOUBLE>)
2 FUNCTION(max#2):
3 FUNCTION(abs#1):
4 FIELD(_ws.ftypes.double)
3 FUNCTION(abs#1):
4 FVALUE(1 <FT_DOUBLE>)
1 FVALUE(0.01 <FT_DOUBLE>)
Instructions:
00000 READ_TREE _ws.ftypes.double -> reg#1
00001 IF_FALSE_GOTO 3
00002 SUBRACT reg#1 - 1 <FT_DOUBLE> -> reg#2
00003 STACK_PUSH reg#2
00004 CALL_FUNCTION abs(reg#2) -> reg#0
00005 STACK_POP 1
00006 IF_FALSE_GOTO 24
00007 READ_TREE _ws.ftypes.double -> reg#1
00008 IF_FALSE_GOTO 9
00009 STACK_PUSH reg#1
00010 CALL_FUNCTION abs(reg#1) -> reg#4
00011 STACK_POP 1
00012 IF_FALSE_GOTO 13
00013 STACK_PUSH reg#4
00014 STACK_PUSH 1 <FT_DOUBLE>
00015 CALL_FUNCTION abs(1 <FT_DOUBLE>) -> reg#5
00016 STACK_POP 1
00017 IF_FALSE_GOTO 18
00018 STACK_PUSH reg#5
00019 CALL_FUNCTION max(reg#5, reg#4) -> reg#3
00020 STACK_POP 2
00021 IF_FALSE_GOTO 24
00022 DIVIDE reg#0 / reg#3 -> reg#6
00023 ANY_LT reg#6 < 0.01 <FT_DOUBLE>
00024 RETURN
We now use a stack to pass arguments to the function. The
stack is implemented as a list of lists (list of registers).
Arguments may still be non-existent to functions (this is
a feature). Functions must check for nil arguments (NULL lists)
and handle that case.
It's somewhat complicated to allow literal values and test compatibility
for different types, both because of lack of type information with
unparsed/literal and also because it is an underdeveloped area in the
code. In my limited testing it was good enough and useful, further
enhancements are left for future work.
Changes the function calling convention to pass the first register
number plus the number of registers after that sequentially. This
allows function with any number of arguments. Functions can still
only return one value.
Adds max() and min() function to select the maximum/minimum value
from any number of arguments, all of the same type. The functions
accept literals too. The return type is the same as the first argument
(cannot be a literal).
Add location tracking as a column offset and length from offset
to the scanner. Our input is a single line only so we don't need
to track line offset.
Record that information in the syntax tree. Return the error location
in dfilter_compile(). Use it in dftest to mark the location of the
error in the filter string. Later it would be nice to use the location
in the GUI as well.
$ dftest "ip.proto == aaaaaa and tcp.port == 123"
Filter: ip.proto == aaaaaa and tcp.port == 123
dftest: "aaaaaa" cannot be found among the possible values for ip.proto.
ip.proto == aaaaaa and tcp.port == 123
^~~~~~
The header ftypes-int.h should not be used outside of epan/ftypes
because it is a private header.
The functions fvalue_free() and fvalue_cleanup() need not and should
not be macros either.
A function is grammatically an identifier that is followed by '(' and ')'
according to some rules. We should avoid assuming a token is a function
just because it matches a registered function name.
Before:
Filter: foobar(http.user_agent) contains "UPDATE"
dftest: Syntax error near "(".
After:
Filter: foobar(http.user_agent) contains "UPDATE"
dftest: The function 'foobar' does not exist.
This has the problem that a function cannot have the same name
as a protocol but that limitation already existed before.
Change all wireshark.org URLs to use https.
Fix some broken links while we're at it.
Change-Id: I161bf8eeca43b8027605acea666032da86f5ea1c
Reviewed-on: https://code.wireshark.org/review/34089
Reviewed-by: Guy Harris <guy@alum.mit.edu>
This function can convert non-string fields into strings. This allows the
user to apply string functions (like contains and matches) to non-string fields.
Examples:
string(frame.number) matches "[13579]$" => for odd frames
string(eth.dst) matches "aa\.bb\.cc\.dd\.ee\..." => to match a group of stations
string(snmp.name) matches "^1.2.3.4" => for all OIDs under a specific node
Change-Id: I18173f50ba5314ecdcd1e4b66c7e8ba5b44257ee
Reviewed-on: https://code.wireshark.org/review/31427
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
It is overlapping to len(), then they've been merged into len()
that now gives the length of any field.
Change-Id: I8e39536a4d15eff4c4b44bb39fd965729cc46951
Reviewed-on: https://code.wireshark.org/review/31462
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot
Reviewed-by: Dario Lombardo <lomato@gmail.com>
len() can now handle FT_STRING, FT_STRINGZ, FT_STRINGZPAD,
FT_UINT_STRING, FT_BYTES, and FT_UINT_BYTES
through the use of fvalue_length()
Change-Id: I53baf2657f7804f64e63e4645d0b84b782ae9b08
Reviewed-on: https://code.wireshark.org/review/21775
Reviewed-by: Michael Mann <mmann78@netscape.net>
Have dfilter_compile() take an additional gchar ** argument, pointing to
a gchar * item that, on error, gets set to point to a g_malloc()ed error
string. That removes one bit of global state from the display filter
parser, and doesn't impose a fixed limit on the error message strings.
Have fvalue_from_string() and fvalue_from_unparsed() take a gchar **
argument, pointer to a gchar * item, rather than an error-reporting
function, and set the gchar * item to point to a g_malloc()ed error
string on an error.
Allow either gchar ** argument to be null; if the argument is null, no
error message is allocated or provided.
Change-Id: Ibd36b8aaa9bf4234aa6efa1e7fb95f7037493b4c
Reviewed-on: https://code.wireshark.org/review/6608
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Couldn't quite eliminate it completely, but it's much improved. Need to figure out where/when to free dfilter_error_msg.
Change-Id: I10216e9546d38e83f69991ded8ec0b3fc8472035
Reviewed-on: https://code.wireshark.org/review/6591
Reviewed-by: Michael Mann <mmann78@netscape.net>
We can just use g_ascii_tolower() and g_ascii_toupper();
Change-Id: I8a88a096d16ce8c60dd9151e5bdddf6747702145
Reviewed-on: https://code.wireshark.org/review/4754
Reviewed-by: Guy Harris <guy@alum.mit.edu>
return an error if the parameter is _no_ string
Bug: 10401
Change-Id: I5643ef05009072538155e63c3178071ed6bab061
Reviewed-on: https://code.wireshark.org/review/4071
Reviewed-by: Martin Kaiser <wireshark@kaiser.cx>
Tested-by: Martin Kaiser <wireshark@kaiser.cx>
Add an FT_STRINGZPAD type, for null-padded strings (typically
fixed-length fields, where the string can be up to the length of the
field, and is null-padded if it's shorter than that), and use it. Use
IS_FT_STRING() in more cases, so that less code needs to know what types
are string types.
Add a tvb_get_stringzpad() routine, which gets null-padded strings.
Currently, it does the same thing that tvb_get_string_enc() does, but
that might change if we don't store string values as null-terminated
strings.
Change-Id: I46f56e130de8f419a19b56ded914e24cc7518a66
Reviewed-on: https://code.wireshark.org/review/1082
Reviewed-by: Guy Harris <guy@alum.mit.edu>
(Using sed : sed -i '/^ \* \$Id\$/,+1 d')
Fix manually some typo (in export_object_dicom.c and crc16-plain.c)
Change-Id: I4c1ae68d1c4afeace8cb195b53c715cf9e1227a8
Reviewed-on: https://code.wireshark.org/review/497
Reviewed-by: Anders Broman <a.broman58@gmail.com>
appropriate for particular FT_ types. This lets us do some more type
checking and lets us use const pointers when appropriate.
Constify a bunch of stuff, and don't cast away constness.
svn path=/trunk/; revision=54811
the ftenum_t for the fvalue's ftype, rather than a pointer to the ftype
(which isn't all that useful except as a handle, unless you import the
internal header).
Have fvalue_to_string_repr() return NULL, rather than failing, if the
fvalue's ftype has no val_to_string_repr method.
This lets us not include the ftypes internal header in
ui/cli/tap-diameter-avp.c.
svn path=/trunk/; revision=53290