Commit Graph

758 Commits

Author SHA1 Message Date
João Valverde fe7bfdf6ca CMake: Require explicit installation of development headers
Develpment headers are a sizeable part of the binary installation
and most users won't ever require them. It's recommended to package
them separately in a devel package or SDK.

Create a CMake installation component for development headers
and add the EXCLUDE_FROM_ALL property.

Headers can be installed using the invocation:

    cmake --install <dir> --component Development
2023-01-18 03:35:13 +00:00
João Valverde edd4295166 MinGW: Fix -Wunknown-pragma 2023-01-13 22:41:04 +00:00
João Valverde 4c9b0d846c CMake: Reverse debug macros
Originally WS_DISABLE_DEBUG was chosen to be
similar to G_DISABLE_ASSERT and NDEBUG.

However generator expressions are essential for modern CMake
but the syntax is weird and having to use negations makes it
ten-fold worse.

Remove the negation. Instead of changing the CMake variable
reverse the macro definition for WS_DISABLE_DEBUG.

The $<CONFIG:cgs> generator expression with multiple config arguments
requires CMake >= 3.19 so we can't use that yet for a further
syntactical simplification.
2023-01-12 00:59:15 +00:00
Philipp Dittmann 9c68879a27 Windows: Fix Release (unused variables)
- 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
2023-01-11 17:50:42 +00:00
João Valverde 313fed6db0 dftest: Add --types option 2023-01-11 01:00:41 +00:00
João Valverde 70e006fc42 dftest: Revert to using "->"
">>" looks like a bit shift. Revert back to "->".
2023-01-11 00:37:44 +00:00
João Valverde 613331f07b dfilter: Disable flex debug trace for release builds
This omits the flex debug code in the binary if the build type is
RelMinSize or Release.

It replaces the "%option debug" stanza with the -d command line
option, to be able to configure the flex behaviour.
2023-01-09 04:03:19 +00:00
João Valverde 840a0d3025 dfilter: Display layer in DFVM dump string 2023-01-08 15:10:43 +00:00
João Valverde fcf97be1e9 dftest: Move a newline insertion
We want the string to not end with a new line for logging purposes
but add the final new line when printing to a file stream.
2023-01-07 22:28:01 +00:00
João Valverde 1861679e81 dfilter: Optimize some scanner patterns
Cleanup flex code. Optimize some patterns to avoid lookups
for field matches for values that are not legal field names.

Improve warning and add some comments.
2023-01-07 21:15:25 +00:00
João Valverde 7641ba7416 dftest: More code cleanups and enhancements 2023-01-07 19:16:16 +00:00
João Valverde a2b23f5a09 dfilter: Fix DFVM function debug output
Add a NULL check. Add missing newlines.

Remove explicit display of number of input arguments.
2023-01-06 02:52:04 +00:00
João Valverde df30299aff dftest: Add -h and improve output format
Experiment with removing the type from the instruction output.

This information is also available with the -s option flag.

Rename -t to -s.
2023-01-06 01:43:42 +00:00
João Valverde 522c74b734 dftest: More CLI options and improve output format 2023-01-05 20:26:42 +00:00
João Valverde fd709a6af3 dfilter: Indent DFVM program using spaces 2023-01-05 20:26:42 +00:00
João Valverde e990b25ea2 dfilter: Remove semcheck arithmetic commute argument
No one is using this so I'd like to explore other
options first to handle constants in arithmetic
expressions that lack type information.

Reverts 3ddb017a88.
2023-01-03 12:46:13 +00:00
João Valverde f37c7c4062 dfilter: Tweak representation for length-1 byte array
Make dfilter byte representation always use ':' for consistency.

Make 1 byte be represented as "XX:" with the colon suffix to
make it nonambiguous that is is a byte and not other type,
like a protocol.

The difference is can be seen in the following programs. In the
before representation it is not obvious at all that the second
"fc" value is a literal bytes value and not the value of the
protocol "fc", although it can be inferred from the lack of
a READ_TREE instruction. In the After we know that "fc:" must
be bytes and not a protocol.

Note that a leading colon is a syntactical expedient to say
"this value with any type is a literal value and not a protocol
field." A terminating colon is just a part of the dfilter
literal bytes syntax.

Before:

Filter: fc == :fc

Syntax tree:
 0 TEST_ANY_EQ:
   1 FIELD(fc <FT_PROTOCOL>)
   1 FVALUE(fc <FT_PROTOCOL>)

Instructions:
00000 READ_TREE		fc <FT_PROTOCOL> -> reg#0
00001 IF_FALSE_GOTO	3
00002 ANY_EQ		reg#0 == fc <FT_PROTOCOL>

After:

Filter: fc == :fc

Syntax tree:
 0 TEST_ANY_EQ:
   1 FIELD(fc <FT_PROTOCOL>)
   1 FVALUE(fc: <FT_PROTOCOL>)

Instructions:
00000 READ_TREE		fc <FT_PROTOCOL> -> reg#0
00001 IF_FALSE_GOTO	3
00002 ANY_EQ		reg#0 == fc: <FT_PROTOCOL>
2023-01-02 02:54:38 +00:00
João Valverde c762d8492b dfilter: Improve debug format 2023-01-02 02:53:21 +00:00
João Valverde f5bfe89785 dfilter: Replace global variable 2023-01-02 01:19:51 +00:00
João Valverde 5d8f495233 dfilter: Minor flex clean up
Replace flex prefix to improve readability.

Remove two no-longer-needed workarounds to suppress warnings.
2023-01-02 01:19:26 +00:00
João Valverde f2218ae5f0 Lemon: Update code and remove cruft
Remove some unused historical files.

Aggressively disable warnings to keep the lemon source
pristine and avoid the maintenance burden for lemon itself.

Lemon has its own lax policy for warnings that doesn't match our
own and they won't accept external patches to remove the
warnings, so just ignore them. Lemon is just executed to generate
code for the Wireshark build and the minor code issues it has
have no influence at runtime.

For lemon generated code we selectively disable some linting
warnings.

Remove patches for lemon and lempar, they are no longer required
with these changes to silence warnings.
2023-01-01 18:18:06 +00:00
João Valverde 6bdc85e37f dfilter: Reject constant expressions
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
    	^~~~~~~~~~~~~~~~~~~~
2022-12-30 18:46:22 +00:00
João Valverde a17fb20550 dfilter: Remove commute argument from semantic check
Take a more conservative, less flexible, maybe more elegant,
approach to type inference for now.
2022-12-30 18:46:22 +00:00
João Valverde 2ff6139307 dfilter: Add a check_nonzero() function
Small refactoring with no functional difference.
2022-12-30 18:46:22 +00:00
João Valverde d3d06c2552 dftest: Add debug command-line options 2022-12-30 13:42:26 +00:00
João Valverde 1400d92724 dfilter: Add compilation warning for ambiguous syntax
$ dfilter 'frame contains fc'
    Filter: frame contains fc

    Warning: Interpreting "fc" as "Fibre Channel". Consider writing :fc or .fc.
    (...)
2022-12-29 23:48:56 +00:00
João Valverde af22c743bd dfilter: Refactor error location for expressions
Underline the whole expression for errors, not just the token.
Implement it for all expressions.
2022-12-29 18:28:54 +00:00
João Valverde 77ef21f86e dfilter: Replace unparsed lexical type and simplify grammar
Remove unparsed lexical type and replace it with identifier
and constant. This separation is still necessary to differentiate
names (fields and function) from literals that look like names
but it has some advantages to do it at the lexical level.

The main advantage is a much cleaner and simplified grammar,
because we only have a single token type for field names, without
any loss of generality (the same name is valid for fields and
function names for example).

The CONSTANT token type is necessary to be different from literal
to provide errors for function rules.
2022-12-29 18:28:54 +00:00
João Valverde bdd00edac8 dfilter: Rename grammar rules 2022-12-29 18:28:54 +00:00
João Valverde 95f705dd8b dfilter: Improve error location for functions
Underline the whole expression if the error is for the function.

Before:

    Filter: frame.number == abs(1, 2)
    dftest: Function abs can only accept 1 arguments.
    	frame.number == abs(1, 2)
    	                ^~~
After:

    Filter: frame.number == abs(1, 2)
    dftest: Function abs can only accept 1 arguments.
    	frame.number == abs(1, 2)
    	                ^~~~~~~~~
2022-12-28 20:26:00 +00:00
João Valverde 6c1ee11172 dfilter: Allow compatible types to be compared in min/max 2022-12-27 21:09:04 +00:00
João Valverde e85f8d4cf1 dfilter: Do not jump when generating function arguments
Instead of "jumping" with length zero to the next sequential
instruction skip generating the no-op jump instruction entirely.
2022-12-27 21:09:04 +00:00
João Valverde f6a02a1e4a dfilter: Preserve function argument order when printing
Instead of printing back to front (from the top of the stack
print them front to back as a user would type them.
2022-12-27 21:09:04 +00:00
João Valverde b19bed43d1 dfilter: Allow constants as the first or only argument to min/max
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
2022-12-27 02:21:06 +00:00
João Valverde 6399f724d9 dfilter: Fix crash with min/max literal argument
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
2022-12-27 01:54:57 +00:00
João Valverde 540b71d738 dfilter: Fix crash with a constant arithmetic expression 2022-12-26 23:55:27 +00:00
João Valverde 3ddb017a88 dfilter: Allow arithmetic expression to commute
Allow an arithmetic expression like 1 + some.field. If we
cannot assign a type to the LHS commute the terms and
try again.

Before:

    Filter: _ws.ftypes.int32 + 1 == 10

    Syntax tree:
     0 TEST_ANY_EQ:
       1 OP_ADD:
         2 FIELD(_ws.ftypes.int32 <FT_INT32>)
         2 FVALUE(1 <FT_INT32>)
       1 FVALUE(10 <FT_INT32>)

    Instructions:
    00000 READ_TREE		_ws.ftypes.int32 <FT_INT32> -> reg#0
    00001 IF_FALSE_GOTO	4
    00002 ADD		reg#0 + 1 <FT_INT32> -> reg#1
    00003 ANY_EQ		reg#1 == 10 <FT_INT32>
    00004 RETURN

    Filter: 1 + _ws.ftypes.int32 == 10
    dftest: Constant arithmetic expression on the LHS is invalid.
    	1 + _ws.ftypes.int32 == 10
    	^

After:

    Filter: _ws.ftypes.int32 + 1 == 10

    Syntax tree:
     0 TEST_ANY_EQ:
       1 OP_ADD:
         2 FIELD(_ws.ftypes.int32 <FT_INT32>)
         2 FVALUE(1 <FT_INT32>)
       1 FVALUE(10 <FT_INT32>)

    Instructions:
    00000 READ_TREE		_ws.ftypes.int32 <FT_INT32> -> reg#0
    00001 IF_FALSE_GOTO	4
    00002 ADD		reg#0 + 1 <FT_INT32> -> reg#1
    00003 ANY_EQ		reg#1 == 10 <FT_INT32>
    00004 RETURN

    Filter: 1 + _ws.ftypes.int32 == 10

    Syntax tree:
     0 TEST_ANY_EQ:
       1 OP_ADD:
         2 FVALUE(1 <FT_INT32>)
         2 FIELD(_ws.ftypes.int32 <FT_INT32>)
       1 FVALUE(10 <FT_INT32>)

    Instructions:
    00000 READ_TREE		_ws.ftypes.int32 <FT_INT32> -> reg#0
    00001 IF_FALSE_GOTO	4
    00002 ADD		1 <FT_INT32> + reg#0 -> reg#1
    00003 ANY_EQ		reg#1 == 10 <FT_INT32>
    00004 RETURN
2022-12-26 20:50:44 +00:00
João Valverde c37552c43c dfilter: Fix an assertion macro 2022-12-26 20:22:21 +00:00
João Valverde 1d544c2077 dfilter: Fix grammar memory leak 2022-12-26 18:48:54 +00:00
João Valverde 079ef9a165 dfilter: Allow comparison relation to commute
Comparison relations should be allowed to commute but they can not
because we need type information to resolve literals to fvalues. For
that reason an expression like "1 == some.field"  is invalid. Solve
that by commuting the relation if the first try did not succeed in
assigning a type to the LHS.

After the second try give up, that means we have a relation with
constants on both sides and that is not semantically valid.

Other relations like "matches" and "contains" are not symmetric and
should not commute anyway.

Before:

    Filter: _ws.ftypes.int32 == 10

    Syntax tree:
     0 TEST_ANY_EQ:
       1 FIELD(_ws.ftypes.int32 <FT_INT32>)
       1 FVALUE(10 <FT_INT32>)

    Instructions:
    00000 READ_TREE		_ws.ftypes.int32 <FT_INT32> -> reg#0
    00001 IF_FALSE_GOTO	3
    00002 ANY_EQ		reg#0 == 10 <FT_INT32>
    00003 RETURN

    Filter: 10 == _ws.ftypes.int32
    dftest: Left side of "==" expression must be a field or function, not 10.
    	10 == _ws.ftypes.int32
    	^~

After:

    Filter: _ws.ftypes.int32 == 10

    Syntax tree:
     0 TEST_ANY_EQ:
       1 FIELD(_ws.ftypes.int32 <FT_INT32>)
       1 FVALUE(10 <FT_INT32>)

    Instructions:
    00000 READ_TREE		_ws.ftypes.int32 <FT_INT32> -> reg#0
    00001 IF_FALSE_GOTO	3
    00002 ANY_EQ		reg#0 == 10 <FT_INT32>
    00003 RETURN

    Filter: 10 == _ws.ftypes.int32

    Syntax tree:
     0 TEST_ANY_EQ:
       1 FVALUE(10 <FT_INT32>)
       1 FIELD(_ws.ftypes.int32 <FT_INT32>)

    Instructions:
    00000 READ_TREE		_ws.ftypes.int32 <FT_INT32> -> reg#0
    00001 IF_FALSE_GOTO	3
    00002 ANY_EQ		10 <FT_INT32> == reg#0
    00003 RETURN
2022-12-26 15:29:50 +00:00
João Valverde 49ec151a7a dfilter: Allow the first DFVM argument to be an fvalue
Do not assert that arg1 must be a register, allow passing constants
as the first argument to allow the arguments to commute freely.
2022-12-26 12:40:23 +00:00
João Valverde 596e0b41d1 dfilter: Change two scanner patterns to camel case 2022-12-26 07:27:40 +00:00
João Valverde 7742b22be4 dfilter: Minor fixups 2022-12-26 04:24:55 +00:00
João Valverde eda80ed336 dfilter: Improve error location for parenthesized expressions 2022-12-26 03:20:30 +00:00
João Valverde 816005fc23 dfilter: Reformat grammar code
Use a consistent style for grammar rules.

Remove a comment that is too generic. The current code should
conform to how Python operates and does not need additional error
checking.
2022-12-24 18:25:11 +00:00
João Valverde b9a5009cb2 dfilter: Clean up scanner code
Clean up some issues flagged by a linter.

Remove hyphen from pattern names and remove an unused start condition.
2022-12-24 15:51:36 +00:00
João Valverde 44511c318d dfilter: Improve error location for expressions
Try to underline the whole expression instead of the
token.
2022-12-23 18:23:14 +00:00
João Valverde 3938b406fb dfilter: Refactor error location tracking
Remove duplicate location struct by adding a new header.

Pass around a structure instead of a pointer.
2022-12-23 18:23:06 +00:00
João Valverde 4e1211de90 dfilter: Add support for negation of arithmetic expressions 2022-12-22 23:51:16 +00:00
João Valverde ba1a85d381 dfilter: Improve arithmetic error messages 2022-12-22 10:13:30 +00:00