2 * Wireshark - Network traffic analyzer
3 * By Gerald Combs <gerald@wireshark.org>
4 * Copyright 2001 Gerald Combs
6 * SPDX-License-Identifier: GPL-2.0-or-later
11 #define WS_LOG_DOMAIN LOG_DOMAIN_DFILTER
15 #include "dfilter-int.h"
17 #include "syntax-tree.h"
18 #include "sttype-field.h"
19 #include "sttype-slice.h"
20 #include "sttype-op.h"
21 #include "sttype-function.h"
22 #include "sttype-pointer.h"
23 #include "sttype-number.h"
25 #include <epan/exceptions.h>
28 #include <wsutil/ws_assert.h>
29 #include <wsutil/wslog.h>
31 #include <ftypes/ftypes.h>
33 #define FAIL(dfw, node, ...) \
35 ws_noisy("Semantic check failed here."); \
36 dfilter_fail_throw(dfw, DF_ERROR_GENERIC, stnode_location(node), __VA_ARGS__); \
39 #define FAIL_HERE(dfw) \
41 ws_noisy("Semantic check failed here."); \
45 #define FAIL_MSG(dfw, node, msg) \
47 ws_noisy("Semantic check failed here."); \
48 dfilter_fail(dfw, DF_ERROR_GENERIC, stnode_location(node), \
54 #define IS_FIELD_ENTITY(ft) \
55 ((ft) == STTYPE_FIELD || \
56 (ft) == STTYPE_REFERENCE)
58 typedef bool (*FtypeCanFunc
)(enum ftenum
);
60 typedef void (*ArithmeticDoFunc
)(dfwork_t
*dfw
, stnode_t
*node
, stnode_t
*arg1
, stnode_t
*arg2
);
63 find_logical_ftype(dfwork_t
*dfw
, stnode_t
*st_node
);
66 check_relation(dfwork_t
*dfw
, stnode_op_t st_op
,
67 FtypeCanFunc can_func
, bool allow_partial_value
,
68 stnode_t
*st_node
, stnode_t
*st_arg1
, stnode_t
*st_arg2
);
71 semcheck(dfwork_t
*dfw
, stnode_t
*st_node
);
74 MK_ERROR_BAD_TYPE
, /* ftype doesn't support value_string */
75 MK_ERROR_NO_STRINGS
, /* ftype supports value string, doesn't have one. */
76 MK_ERROR_BAD_VALUE
, /* ftype has value_string, this value isn't in it. */
77 MK_ERROR
= MK_ERROR_BAD_VALUE
,
84 mk_fvalue_from_val_string(dfwork_t
*dfw
, header_field_info
*hfinfo
, const char *s
, stnode_t
*st
);
87 op_is_equality(stnode_op_t op
)
90 case STNODE_OP_ALL_EQ
:
91 case STNODE_OP_ANY_EQ
:
92 case STNODE_OP_ALL_NE
:
93 case STNODE_OP_ANY_NE
:
95 case STNODE_OP_NOT_IN
:
102 /* Compares to ftenum_t's and decides if they're
103 * compatible or not (if they're the same basic type) */
105 compatible_ftypes(ftenum_t a
, ftenum_t b
)
111 case FT_ABSOLUTE_TIME
: /* XXX - README.dissector says the time types are compatible */
112 case FT_RELATIVE_TIME
:
113 case FT_IEEE_11073_SFLOAT
: /* XXX - should be able to compare with DOUBLE (#19011) */
114 case FT_IEEE_11073_FLOAT
: /* XXX - should be able to compare with DOUBLE */
120 case FT_FLOAT
: /* XXX - should be able to compare with INT */
121 case FT_DOUBLE
: /* XXX - should be able to compare with INT */
140 return (b
== FT_ETHER
|| b
== FT_BYTES
|| b
== FT_UINT_BYTES
|| b
== FT_OID
|| b
== FT_VINES
|| b
== FT_FCWWN
|| b
== FT_REL_OID
|| b
== FT_SYSTEM_ID
|| b
== FT_EUI64
);
149 return ftype_can_val_to_uinteger(b
);
155 return ftype_can_val_to_uinteger64(b
);
161 return ftype_can_val_to_sinteger(b
);
167 return ftype_can_val_to_sinteger64(b
);
173 case FT_STRINGZTRUNC
:
175 return FT_IS_STRING(b
);
179 ASSERT_FTYPE_NOT_REACHED(a
);
182 ws_assert_not_reached();
187 resolve_unparsed(dfwork_t
*dfw
, stnode_t
*st
, bool strict
)
189 if (stnode_type_id(st
) != STTYPE_UNPARSED
)
192 header_field_info
*hfinfo
= dfilter_resolve_unparsed(stnode_data(st
), dfw
->deprecated
);
194 stnode_replace(st
, STTYPE_FIELD
, hfinfo
);
196 FAIL(dfw
, st
, "\"%s\" is not a valid protocol or protocol field.", stnode_todisplay(st
));
198 stnode_mutate(st
, STTYPE_LITERAL
);
201 /* Don't set the error message if it's already set. */
202 #define SET_ERROR(dfw, str) \
204 if ((str) != NULL && (dfw)->error == NULL) { \
205 (dfw)->error = df_error_new(DF_ERROR_GENERIC, str, NULL); \
212 /* Transforms a syntax node into a value and sets the error message on failure. */
214 dfilter_fvalue_from_literal(dfwork_t
*dfw
, ftenum_t ftype
, stnode_t
*st
,
215 bool allow_partial_value
, header_field_info
*hfinfo_value_string
)
218 const char *s
= stnode_data(st
);
219 char *error_message
= NULL
;
222 fv
= fvalue_from_literal(ftype
, s
, allow_partial_value
, &error_message
);
224 g_free(error_message
); // error_message is expected to be null
225 stnode_replace(st
, STTYPE_FVALUE
, fv
);
228 SET_ERROR(dfw
, error_message
);
230 if (hfinfo_value_string
) {
231 /* check value_string */
232 res
= mk_fvalue_from_val_string(dfw
, hfinfo_value_string
, s
, st
);
234 * Ignore previous errors if this can be mapped
235 * to an item from value_string.
237 if (res
> MK_ERROR
) {
238 df_error_free(&dfw
->error
);
239 add_compile_warning(dfw
, "Interpreting the symbol \u2039%s\u203A as a %s value string. "
240 "Writing value strings without double quotes is deprecated. "
241 "Please use \u2039\"%s\"\u203A instead",
242 stnode_token(st
), ftype_pretty_name(hfinfo_value_string
->type
), stnode_token(st
));
243 return res
== MK_OK_STRING
;
248 dfw_set_error_location(dfw
, stnode_location(st
));
250 ws_assert_not_reached();
253 /* Transforms a syntax node into a value and sets the error message on failure. */
255 dfilter_fvalue_from_string(dfwork_t
*dfw
, ftenum_t ftype
, stnode_t
*st
,
256 header_field_info
*hfinfo_value_string
)
259 const GString
*gs
= stnode_string(st
);
260 char *error_message
= NULL
;
263 fv
= fvalue_from_string(ftype
, gs
->str
, gs
->len
, &error_message
);
265 g_free(error_message
); // error_message is expected to be null
266 stnode_replace(st
, STTYPE_FVALUE
, fv
);
269 SET_ERROR(dfw
, error_message
);
271 if (hfinfo_value_string
) {
272 res
= mk_fvalue_from_val_string(dfw
, hfinfo_value_string
, gs
->str
, st
);
274 * Ignore previous errors if this can be mapped
275 * to an item from value_string.
277 if (res
!= MK_ERROR
) {
278 df_error_free(&dfw
->error
);
279 return res
== MK_OK_STRING
;
284 dfw_set_error_location(dfw
, stnode_location(st
));
286 ws_assert_not_reached();
290 dfilter_fvalue_from_charconst(dfwork_t
*dfw
, ftenum_t ftype
, stnode_t
*st
)
293 unsigned long *nump
= stnode_data(st
);
294 char *error_message
= NULL
;
296 fv
= fvalue_from_charconst(ftype
, *nump
, &error_message
);
298 g_free(error_message
); // error_message is expected to be null
299 stnode_replace(st
, STTYPE_FVALUE
, fv
);
302 SET_ERROR(dfw
, error_message
);
305 dfw_set_error_location(dfw
, stnode_location(st
));
307 ws_assert_not_reached();
311 dfilter_fvalue_from_number(dfwork_t
*dfw
, ftenum_t ftype
, stnode_t
*st
)
314 const char *s
= stnode_token(st
);
315 char *error_message
= NULL
;
318 num_type
= sttype_number_get_type(st
);
320 if (ftype
== FT_SCALAR
) {
321 /* If a scalar was requested then transform the number
322 * syntax node to an fvalue according to its lexical
323 * type (integer or float). */
333 ws_assert_not_reached();
339 fv
= fvalue_from_sinteger64(ftype
, s
, sttype_number_get_integer(st
), &error_message
);
343 fv
= fvalue_from_uinteger64(ftype
, s
, sttype_number_get_unsigned(st
), &error_message
);
347 fv
= fvalue_from_floating(ftype
, s
, sttype_number_get_float(st
), &error_message
);
351 ws_assert_not_reached();
355 g_free(error_message
); // error_message is expected to be null
356 stnode_replace(st
, STTYPE_FVALUE
, fv
);
359 SET_ERROR(dfw
, error_message
);
362 dfw_set_error_location(dfw
, stnode_location(st
));
364 ws_assert_not_reached();
367 /* Creates a FT_BOOLEAN fvalue with a given value. */
369 mk_boolean_fvalue(bool val
)
373 fv
= fvalue_new(FT_BOOLEAN
);
374 fvalue_set_uinteger64(fv
, val
);
379 /* Creates a FT_STRING fvalue with a given value. */
381 mk_string_fvalue(const char *str
)
383 fvalue_t
*fv
= fvalue_new(FT_STRING
);
384 fvalue_set_string(fv
, str
);
388 /* Creates a FT_UINT64 fvalue with a given value. */
390 mk_uint64_fvalue(uint64_t val
)
392 fvalue_t
*fv
= fvalue_new(FT_UINT64
);
393 fvalue_set_uinteger64(fv
, val
);
397 static enum mk_result
398 mk_fvalue_from_hfinfo(const header_field_info
*hfinfo
, const char *s
, uint64_t *valp
)
401 /* If registration of non-compatible fields to the same abbrev were
402 * checked, we could do this check up front for the first hfinfo only -
403 * except for FT_FRAMENUM, which is compatible with the integer types
404 * and overloads strings.
405 * (We could instead say that FT_FRAMENUM is compatible for comparing
406 * with integer types but not for registering to the same abbrev.)
408 switch(hfinfo
->type
) {
410 case FT_PROTOCOL
: /* hfinfo->strings contains the protocol_t */
411 case FT_FLOAT
: /* XXX - FT_FLOAT can have strings for BASE_CUSTOM */
412 case FT_DOUBLE
: /* XXX - FT_DOUBLE can have strings for BASE_CUSTOM */
413 case FT_IEEE_11073_SFLOAT
:
414 case FT_IEEE_11073_FLOAT
:
415 case FT_ABSOLUTE_TIME
:
416 case FT_RELATIVE_TIME
:
430 case FT_STRINGZTRUNC
:
436 case FT_FRAMENUM
: /* hfinfo->strings contains ft_framenum_type_t, not strings */
437 return MK_ERROR_BAD_TYPE
;
461 ASSERT_FTYPE_NOT_REACHED(hfinfo
->type
);
465 /* Always handle FT_BOOLEAN (fallback to default tfs). */
466 if (hfinfo
->type
== FT_BOOLEAN
) {
467 static const true_false_string default_tf
= { "True", "False" };
468 const true_false_string
*tf
;
469 tf
= hfinfo
->strings
? (const true_false_string
*)hfinfo
->strings
: &default_tf
;
471 if (g_ascii_strcasecmp(s
, tf
->true_string
) == 0) {
473 return MK_OK_BOOLEAN
;
475 if (g_ascii_strcasecmp(s
, tf
->false_string
) == 0) {
477 return MK_OK_BOOLEAN
;
482 /* Do val_strings exist? */
483 if (!hfinfo
->strings
) {
484 return MK_ERROR_NO_STRINGS
;
487 uint64_t val
= 0, val_max
= 0;
490 if (hfinfo
->display
& BASE_RANGE_STRING
) {
491 const range_string
*vals
= (const range_string
*)hfinfo
->strings
;
493 while (vals
->strptr
!= NULL
&& count
<= 1) {
494 if (g_ascii_strcasecmp(s
, vals
->strptr
) == 0) {
495 val
= vals
->value_min
;
496 val_max
= vals
->value_max
;
502 // More than one match, use a string.
505 else if (count
== 1) {
506 // If the range has a single value use an integer.
507 // Otherwise use a string.
508 if (val
== val_max
) {
517 else if (hfinfo
->display
& BASE_VAL64_STRING
) {
518 const val64_string
*vals
= (const val64_string
*)hfinfo
->strings
;
519 if (hfinfo
->display
& BASE_EXT_STRING
)
520 vals
= VAL64_STRING_EXT_VS_P((const val64_string_ext
*) vals
);
522 while (vals
->strptr
!= NULL
&& count
<= 1) {
523 if (g_ascii_strcasecmp(s
, vals
->strptr
) == 0) {
530 // More than one match, use a string.
533 else if (count
== 1) {
534 // Only one match, convert string to number.
539 else if (hfinfo
->display
== BASE_CUSTOM
) {
540 /* We don't have a string catalog to compare to so just assume
541 * the provided string is a valid custom representation. */
542 if (FT_IS_INTEGER(hfinfo
->type
)) {
543 /* Should always be true due to type check above. */
546 /* FT_FLOAT and FT_DOUBLE can have BASE_CUSTOM functions but
547 * they were disallowed above. Maybe they should be allowed?
548 * That would take changes in dfvm.c try_value_string as well.
552 const value_string
*vals
= (const value_string
*)hfinfo
->strings
;
553 if (hfinfo
->display
& BASE_EXT_STRING
)
554 vals
= VALUE_STRING_EXT_VS_P((const value_string_ext
*) vals
);
556 while (vals
->strptr
!= NULL
&& count
<= 1) {
557 if (g_ascii_strcasecmp(s
, vals
->strptr
) == 0) {
564 // More than one match, use a string.
567 else if (count
== 1) {
568 // Only one match, convert string to number.
576 /* Try to make an fvalue from a string using a value_string or true_false_string.
577 * This works only for ftypes that are integers.
578 * If the mapping number<->string is unique convert the string to a number
579 * by inverting the value string function.
580 * Otherwise we compile it as a string and map the field value at runtime
581 * to a string for the comparison.
583 static enum mk_result
584 mk_fvalue_from_val_string(dfwork_t
*dfw
, header_field_info
*hfinfo
, const char *s
, stnode_t
*st
)
590 /* We might have more than one hfinfo with the same abbreviation. (#19111)
591 * We can optimize to a number (or boolean) test if all fields map the
592 * same value (and only that value) to the string.
593 * Otherwise, allow a string match if at least one field with the
594 * abbreviation has a value string with that string as an entry.
596 while (hfinfo
->same_name_prev_id
!= -1) {
597 /* Rewind (shouldn't be necessary.) */
598 hfinfo
= proto_registrar_get_nth(hfinfo
->same_name_prev_id
);
600 /* Types of failures:
601 * 1. ftype doesn't support value strings
602 * 2. ftype supports value strings, but hfinfo doesn't have one
603 * 3. hfinfo has a value string, but s is not among the possible values
605 * These are distinguished only for what error message, if any, we'll
606 * produce (and whether it overrides any earlier error message.)
607 * Report the highest number error from any hfinfo (i.e., if at least
608 * one field does have a value string, prefer saying that "s" was not
609 * among its values to reporting that the other fields didn't have
612 res
= mk_fvalue_from_hfinfo(hfinfo
, s
, &val
);
614 while (res
!= MK_OK_STRING
&& hfinfo
->same_name_next
) {
615 enum mk_result prev_res
= res
;
616 uint64_t prev_val
= val
;
617 hfinfo
= hfinfo
->same_name_next
;
619 res
= mk_fvalue_from_hfinfo(hfinfo
, s
, &val
);
623 case MK_ERROR_BAD_TYPE
:
624 case MK_ERROR_NO_STRINGS
:
625 case MK_ERROR_BAD_VALUE
:
626 if (prev_res
> MK_ERROR
) {
627 /* An earlier hfinfo has s, but not this.
628 * Fall back to a string match. */
631 res
= MAX(res
, prev_res
);
637 if (prev_res
!= res
|| val
!= prev_val
) {
638 /* This field maps a single value to s,
639 * but an earlier field maps a different
640 * value or fails to match. Fall back to
654 fv
= mk_boolean_fvalue((bool)val
);
658 fv
= mk_uint64_fvalue(val
);
662 fv
= mk_string_fvalue(s
);
665 case MK_ERROR_BAD_TYPE
:
669 case MK_ERROR_NO_STRINGS
:
670 dfilter_fail(dfw
, DF_ERROR_GENERIC
, stnode_location(st
), "%s cannot accept strings as values.",
676 df_error_free(&dfw
->error
);
677 if (hfinfo
->type
== FT_BOOLEAN
&& hfinfo
->same_name_next
== NULL
) {
678 // For a boolean (with only one field for the abbreviation),
679 // it's easy to show all possible values.
680 dfilter_fail(dfw
, DF_ERROR_GENERIC
, stnode_location(st
), "expected \"%s\" or \"%s\", not \"%s\" for %s.",
681 tfs_get_string(true, hfinfo
->strings
), tfs_get_string(false, hfinfo
->strings
),
684 dfilter_fail(dfw
, DF_ERROR_GENERIC
, stnode_location(st
), "\"%s\" cannot be found among the possible values for %s.",
691 df_error_free(&dfw
->error
);
692 stnode_replace(st
, STTYPE_FVALUE
, fv
);
699 is_bytes_type(enum ftenum type
)
718 case FT_IEEE_11073_SFLOAT
:
719 case FT_IEEE_11073_FLOAT
:
720 case FT_ABSOLUTE_TIME
:
721 case FT_RELATIVE_TIME
:
729 case FT_STRINGZTRUNC
:
754 ASSERT_FTYPE_NOT_REACHED(type
);
757 ws_assert_not_reached();
762 get_slice_ftype(dfwork_t
*dfw
, stnode_t
*st_node
)
764 stnode_t
*entity1
= sttype_slice_entity(st_node
);
766 resolve_unparsed(dfw
, entity1
, true);
767 ftenum_t ftype
= get_logical_ftype(dfw
, entity1
);
768 return FT_IS_STRING(ftype
) ? FT_STRING
: FT_BYTES
;
772 get_function_ftype(dfwork_t
*dfw
, stnode_t
*st_node
)
774 df_func_def_t
*funcdef
;
778 funcdef
= sttype_function_funcdef(st_node
);
779 params
= sttype_function_params(st_node
);
780 nparams
= g_slist_length(params
);
782 if (funcdef
->return_ftype
!= FT_NONE
)
783 return funcdef
->return_ftype
;
787 for (GSList
*l
= params
; l
!= NULL
; l
= l
->next
) {
788 resolve_unparsed(dfw
, l
->data
, false);
789 ftenum_t ftype
= get_logical_ftype(dfw
, l
->data
);
790 if (ftype
!= FT_NONE
) {
798 get_logical_ftype(dfwork_t
*dfw
, stnode_t
*st_node
)
800 stnode_t
*st_arg1
, *st_arg2
;
803 switch(stnode_type_id(st_node
)) {
805 case STTYPE_REFERENCE
:
806 return sttype_field_ftenum(st_node
);
808 case STTYPE_UNPARSED
:
809 resolve_unparsed(dfw
, st_node
, true);
810 return sttype_field_ftenum(st_node
);
814 case STTYPE_CHARCONST
:
818 case STTYPE_FUNCTION
:
819 return get_function_ftype(dfw
, st_node
);
821 case STTYPE_ARITHMETIC
:
823 sttype_oper_get(st_node
, NULL
, &st_arg1
, &st_arg2
);
824 if (st_arg1
&& (ft
= get_logical_ftype(dfw
, st_arg1
)) != FT_NONE
)
826 if (st_arg2
&& (ft
= get_logical_ftype(dfw
, st_arg2
)) != FT_NONE
)
831 return get_slice_ftype(dfw
, st_node
);
834 case STTYPE_UNINITIALIZED
:
835 case STTYPE_NUM_TYPES
:
838 ASSERT_STTYPE_NOT_REACHED(stnode_type_id(st_node
));
841 ws_assert_not_reached();
845 find_logical_ftype(dfwork_t
*dfw
, stnode_t
*st_node
)
847 ftenum_t ftype
= get_logical_ftype(dfw
, st_node
);
848 if (ftype
== FT_NONE
) {
849 FAIL(dfw
, st_node
, "Constant expression is invalid");
854 /* Check the semantics of an existence test. */
856 check_exists(dfwork_t
*dfw
, stnode_t
*st_arg1
)
858 ftenum_t ftype
= FT_NONE
;
859 resolve_unparsed(dfw
, st_arg1
, true);
863 switch (stnode_type_id(st_arg1
)) {
867 case STTYPE_REFERENCE
:
869 if (dfw
->flags
& DF_RETURN_VALUES
) {
870 ftype
= sttype_field_ftenum(st_arg1
);
875 case STTYPE_CHARCONST
:
877 FAIL(dfw
, st_arg1
, "%s is neither a field nor a protocol name.",
878 stnode_todisplay(st_arg1
));
881 case STTYPE_UNPARSED
:
882 case STTYPE_FUNCTION
:
884 case STTYPE_UNINITIALIZED
:
885 case STTYPE_NUM_TYPES
:
889 case STTYPE_ARITHMETIC
:
891 ASSERT_STTYPE_NOT_REACHED(stnode_type_id(st_arg1
));
898 check_slice(dfwork_t
*dfw
, stnode_t
*st
, ftenum_t logical_ftype
)
901 header_field_info
*hfinfo1
;
903 ftenum_t ftype1
= FT_NONE
;
907 entity1
= sttype_slice_entity(st
);
909 resolve_unparsed(dfw
, entity1
, true);
910 sttype1
= stnode_type_id(entity1
);
916 case STTYPE_REFERENCE
:
917 hfinfo1
= sttype_field_hfinfo(entity1
);
918 ftype1
= sttype_field_ftenum(entity1
);
920 if (!ftype_can_slice(ftype1
)) {
921 FAIL(dfw
, entity1
, "\"%s\" is a %s and cannot be sliced into a sequence of bytes.",
922 hfinfo1
->abbrev
, ftype_pretty_name(ftype1
));
926 case STTYPE_FUNCTION
:
927 ftype1
= check_function(dfw
, entity1
, logical_ftype
);
929 if (!ftype_can_slice(ftype1
)) {
930 FAIL(dfw
, entity1
, "Return value of function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
931 sttype_function_name(entity1
), ftype_pretty_name(ftype1
));
936 ftype1
= check_slice(dfw
, entity1
, logical_ftype
);
941 case STTYPE_CHARCONST
:
943 FAIL(dfw
, entity1
, "Range is not supported for entity %s",
944 stnode_todisplay(entity1
));
946 case STTYPE_UNPARSED
:
947 case STTYPE_UNINITIALIZED
:
948 case STTYPE_NUM_TYPES
:
952 case STTYPE_ARITHMETIC
:
954 ASSERT_STTYPE_NOT_REACHED(sttype1
);
958 return FT_IS_STRING(ftype1
) ? FT_STRING
: FT_BYTES
;
962 convert_to_bytes(stnode_t
*arg
)
967 entity1
= stnode_dup(arg
);
968 rn
= drange_node_new();
969 drange_node_set_start_offset(rn
, 0);
970 drange_node_set_to_the_end(rn
);
972 stnode_replace(arg
, STTYPE_SLICE
, NULL
);
973 sttype_slice_set1(arg
, entity1
, rn
);
977 check_function(dfwork_t
*dfw
, stnode_t
*st_node
, ftenum_t logical_ftype
)
979 df_func_def_t
*funcdef
;
985 funcdef
= sttype_function_funcdef(st_node
);
986 params
= sttype_function_params(st_node
);
987 nparams
= g_slist_length(params
);
989 if (nparams
< funcdef
->min_nargs
) {
990 FAIL(dfw
, st_node
, "Function %s needs at least %u arguments.",
991 funcdef
->name
, funcdef
->min_nargs
);
992 } else if (funcdef
->max_nargs
> 0 && nparams
> funcdef
->max_nargs
) {
993 FAIL(dfw
, st_node
, "Function %s can only accept %u arguments.",
994 funcdef
->name
, funcdef
->max_nargs
);
997 return funcdef
->semcheck_param_function(dfw
, funcdef
->name
, logical_ftype
, params
,
998 stnode_location(st_node
));
1001 /* If the LHS of a relation test is a FIELD, run some checks
1002 * and possibly some modifications of syntax tree nodes. */
1004 check_relation_LHS_FIELD(dfwork_t
*dfw
, stnode_op_t st_op
,
1005 FtypeCanFunc can_func
, bool allow_partial_value
,
1007 stnode_t
*st_arg1
, stnode_t
*st_arg2
)
1010 header_field_info
*hfinfo1
;
1011 ftenum_t ftype1
, ftype2
;
1012 bool mk_val_string
= false;
1016 if (stnode_type_id(st_arg1
) == STTYPE_FIELD
)
1019 hfinfo1
= sttype_field_hfinfo(st_arg1
);
1020 ftype1
= sttype_field_ftenum(st_arg1
);
1021 if (!can_func(ftype1
)) {
1022 /* For "matches", implicitly convert to the value string, if
1023 * there is one. (FT_FRAMENUM and FT_PROTOCOL have a pointer
1024 * to something other than a value string in their ->strings
1025 * member, though we can't get here for a FT_PROTOCOL because
1026 * it supports "matches" on its bytes without conversion.)
1028 if (st_op
== STNODE_OP_MATCHES
&& hfinfo1
->strings
!= NULL
&& hfinfo1
->type
!= FT_FRAMENUM
&& hfinfo1
->type
!= FT_PROTOCOL
) {
1029 sttype_field_set_value_string(st_arg1
, true);
1032 FAIL(dfw
, st_arg1
, "%s (type=%s) cannot participate in %s comparison.",
1033 hfinfo1
->abbrev
, ftype_pretty_name(ftype1
),
1034 stnode_todisplay(st_node
));
1038 ftype1
= sttype_field_ftenum(st_arg1
);
1039 type2
= stnode_type_id(st_arg2
);
1041 if (IS_FIELD_ENTITY(type2
)) {
1042 ftype2
= sttype_field_ftenum(st_arg2
);
1044 if (!compatible_ftypes(ftype1
, ftype2
)) {
1045 FAIL(dfw
, st_arg2
, "%s and %s are not of compatible types.",
1046 stnode_todisplay(st_arg1
), stnode_todisplay(st_arg2
));
1048 /* Do this check even though you'd think that if
1049 * they're compatible, then can_func() would pass. */
1050 if (!can_func(ftype2
)) {
1051 FAIL(dfw
, st_arg2
, "%s (type=%s) cannot participate in specified comparison.",
1052 stnode_todisplay(st_arg2
), ftype_pretty_name(ftype2
));
1054 if (type2
== STTYPE_FIELD
) {
1058 else if (type2
== STTYPE_STRING
|| type2
== STTYPE_LITERAL
) {
1060 /* Skip incompatible fields */
1061 while (hfinfo1
->same_name_prev_id
!= -1 &&
1062 ((type2
== STTYPE_STRING
&& ftype1
!= FT_STRING
&& ftype1
!= FT_STRINGZ
) ||
1063 (type2
!= STTYPE_STRING
&& (ftype1
== FT_STRING
|| ftype1
== FT_STRINGZ
)))) {
1064 hfinfo1
= proto_registrar_get_nth(hfinfo1
->same_name_prev_id
);
1065 ftype1
= hfinfo1
->type
;
1068 if (type2
== STTYPE_STRING
) {
1069 mk_val_string
= dfilter_fvalue_from_string(dfw
, ftype1
, st_arg2
, hfinfo1
);
1072 mk_val_string
= dfilter_fvalue_from_literal(dfw
, ftype1
, st_arg2
, allow_partial_value
, hfinfo1
);
1074 if (mk_val_string
) {
1075 sttype_field_set_value_string(st_arg1
, true);
1076 // Value strings can only be ordered if they are numerical.
1077 // Don't try to order them lexicographically, that's not
1078 // what users expect.
1079 if (!op_is_equality(st_op
)) {
1080 FAIL(dfw
, st_arg2
, "Cannot use order comparisons with \"%s\" "
1081 "because the value string cannot be uniquely converted to an integer.",
1082 stnode_todisplay(st_arg2
));
1086 else if (type2
== STTYPE_CHARCONST
) {
1087 dfilter_fvalue_from_charconst(dfw
, ftype1
, st_arg2
);
1089 else if (type2
== STTYPE_NUMBER
) {
1090 dfilter_fvalue_from_number(dfw
, ftype1
, st_arg2
);
1092 else if (type2
== STTYPE_SLICE
) {
1093 ftype2
= check_slice(dfw
, st_arg2
, ftype1
);
1095 if (!compatible_ftypes(ftype1
, ftype2
)) {
1096 FAIL(dfw
, st_arg2
, "%s and %s are not of compatible types.",
1097 stnode_todisplay(st_arg1
), stnode_todisplay(st_arg2
));
1099 if (!can_func(ftype2
)) {
1100 FAIL(dfw
, st_arg2
, "%s (type=%s) cannot participate in specified comparison.",
1101 stnode_todisplay(st_arg2
), ftype_pretty_name(ftype2
));
1104 if (!is_bytes_type(ftype1
)) {
1105 if (!ftype_can_slice(ftype1
)) {
1106 FAIL(dfw
, st_arg1
, "\"%s\" is a %s and cannot be converted into a sequence of bytes.",
1108 ftype_pretty_name(ftype1
));
1111 /* Convert entire field to bytes */
1112 convert_to_bytes(st_arg1
);
1115 else if (type2
== STTYPE_FUNCTION
) {
1116 ftype2
= check_function(dfw
, st_arg2
, ftype1
);
1118 if (!compatible_ftypes(ftype1
, ftype2
)) {
1119 FAIL(dfw
, st_arg2
, "%s (type=%s) and return value of %s() (type=%s) are not of compatible types.",
1120 hfinfo1
->abbrev
, ftype_pretty_name(ftype1
),
1121 sttype_function_name(st_arg2
), ftype_pretty_name(ftype2
));
1124 if (!can_func(ftype2
)) {
1125 FAIL(dfw
, st_arg2
, "return value of %s() (type=%s) cannot participate in specified comparison.",
1126 sttype_function_name(st_arg2
), ftype_pretty_name(ftype2
));
1129 else if (type2
== STTYPE_PCRE
) {
1130 ws_assert(st_op
== STNODE_OP_MATCHES
);
1132 else if (type2
== STTYPE_ARITHMETIC
) {
1133 ftype2
= check_arithmetic(dfw
, st_arg2
, ftype1
);
1135 if (!compatible_ftypes(ftype1
, ftype2
)) {
1136 FAIL(dfw
, st_arg2
, "%s and %s are not of compatible types.",
1137 stnode_todisplay(st_arg1
), stnode_todisplay(st_arg2
));
1140 if (!can_func(ftype2
)) {
1141 FAIL(dfw
, st_arg2
, "%s (type=%s) cannot participate in specified comparison.",
1142 stnode_todisplay(st_arg2
), ftype_pretty_name(ftype2
));
1146 ASSERT_STTYPE_NOT_REACHED(type2
);
1151 check_relation_LHS_FVALUE(dfwork_t
*dfw
, stnode_op_t st_op
,
1152 FtypeCanFunc can_func
, bool allow_partial_value
,
1154 stnode_t
*st_arg1
, stnode_t
*st_arg2
,
1155 ftenum_t logical_ftype
)
1157 sttype_id_t type1
, type2
;
1158 header_field_info
*hfinfo2
= NULL
;
1160 bool mk_val_string
= false;
1164 type2
= stnode_type_id(st_arg2
);
1166 if (IS_FIELD_ENTITY(type2
)) {
1167 hfinfo2
= sttype_field_hfinfo(st_arg2
);
1168 ftype2
= sttype_field_ftenum(st_arg2
);
1170 if (!can_func(ftype2
)) {
1171 FAIL(dfw
, st_arg2
, "%s (type=%s) cannot participate in specified comparison.",
1172 stnode_todisplay(st_arg2
), ftype_pretty_name(ftype2
));
1174 if (type2
== STTYPE_FIELD
) {
1178 else if (type2
== STTYPE_STRING
||
1179 type2
== STTYPE_LITERAL
||
1180 type2
== STTYPE_CHARCONST
||
1181 type2
== STTYPE_NUMBER
||
1182 type2
== STTYPE_PCRE
) {
1183 FAIL(dfw
, st_node
, "Constant expression is invalid.");
1185 else if (type2
== STTYPE_SLICE
) {
1186 ftype2
= check_slice(dfw
, st_arg2
, logical_ftype
);
1188 if (!can_func(ftype2
)) {
1189 FAIL(dfw
, st_arg2
, "%s (type=%s) cannot participate in specified comparison.",
1190 stnode_todisplay(st_arg2
), ftype_pretty_name(ftype2
));
1193 else if (type2
== STTYPE_FUNCTION
) {
1194 ftype2
= check_function(dfw
, st_arg2
, logical_ftype
);
1196 if (!can_func(ftype2
)) {
1197 FAIL(dfw
, st_arg2
, "return value of %s() (type=%s) cannot participate in specified comparison.",
1198 sttype_function_name(st_arg2
), ftype_pretty_name(ftype2
));
1201 else if (type2
== STTYPE_ARITHMETIC
) {
1202 ftype2
= check_arithmetic(dfw
, st_arg2
, logical_ftype
);
1204 if (!can_func(ftype2
)) {
1205 FAIL(dfw
, st_arg2
, "%s (type=%s) cannot participate in specified comparison.",
1206 stnode_todisplay(st_arg2
), ftype_pretty_name(ftype2
));
1210 ASSERT_STTYPE_NOT_REACHED(type2
);
1213 type1
= stnode_type_id(st_arg1
);
1214 if (type1
== STTYPE_STRING
) {
1215 mk_val_string
= dfilter_fvalue_from_string(dfw
, ftype2
, st_arg1
, hfinfo2
);
1217 else if (type1
== STTYPE_LITERAL
) {
1218 mk_val_string
= dfilter_fvalue_from_literal(dfw
, ftype2
, st_arg1
, allow_partial_value
, hfinfo2
);
1220 else if (type1
== STTYPE_CHARCONST
) {
1221 dfilter_fvalue_from_charconst(dfw
, ftype2
, st_arg1
);
1223 else if (type1
== STTYPE_NUMBER
) {
1224 dfilter_fvalue_from_number(dfw
, ftype2
, st_arg1
);
1227 ASSERT_STTYPE_NOT_REACHED(type1
);
1229 if (mk_val_string
) {
1230 sttype_field_set_value_string(st_arg2
, true);
1231 // Value strings can only be ordered if they are numerical.
1232 // Don't try to order them lexicographically, that's not
1233 // what users expect.
1234 if (!op_is_equality(st_op
)) {
1235 FAIL(dfw
, st_arg1
, "Cannot use order comparisons with \"%s\" "
1236 "because the value string cannot be uniquely converted to an integer.",
1237 stnode_todisplay(st_arg1
));
1243 check_relation_LHS_SLICE(dfwork_t
*dfw
, stnode_op_t st_op _U_
,
1244 FtypeCanFunc can_func _U_
,
1245 bool allow_partial_value
,
1246 stnode_t
*st_node _U_
,
1247 stnode_t
*st_arg1
, stnode_t
*st_arg2
,
1248 ftenum_t logical_ftype
)
1251 ftenum_t ftype1
, ftype2
;
1255 ftype1
= check_slice(dfw
, st_arg1
, logical_ftype
);
1256 if (!can_func(ftype1
)) {
1257 FAIL(dfw
, st_arg1
, "%s cannot participate in %s comparison.",
1258 stnode_todisplay(st_arg1
), stnode_todisplay(st_node
));
1261 type2
= stnode_type_id(st_arg2
);
1263 if (IS_FIELD_ENTITY(type2
)) {
1264 ftype2
= sttype_field_ftenum(st_arg2
);
1266 if (!is_bytes_type(ftype2
)) {
1267 if (!ftype_can_slice(ftype2
)) {
1268 FAIL(dfw
, st_arg2
, "\"%s\" is a %s and cannot be converted into a sequence of bytes.",
1269 stnode_todisplay(st_arg2
),
1270 ftype_pretty_name(ftype2
));
1273 /* Convert entire field to bytes */
1274 convert_to_bytes(st_arg2
);
1276 if (type2
== STTYPE_FIELD
) {
1280 else if (type2
== STTYPE_STRING
) {
1281 dfilter_fvalue_from_string(dfw
, ftype1
, st_arg2
, NULL
);
1283 else if (type2
== STTYPE_LITERAL
) {
1284 dfilter_fvalue_from_literal(dfw
, ftype1
, st_arg2
, allow_partial_value
, NULL
);
1286 else if (type2
== STTYPE_CHARCONST
) {
1287 dfilter_fvalue_from_charconst(dfw
, ftype1
, st_arg2
);
1289 else if (type2
== STTYPE_NUMBER
) {
1290 dfilter_fvalue_from_number(dfw
, ftype1
, st_arg2
);
1292 else if (type2
== STTYPE_SLICE
) {
1293 ftype2
= check_slice(dfw
, st_arg2
, ftype1
);
1295 if (!compatible_ftypes(ftype1
, ftype2
)) {
1296 FAIL(dfw
, st_arg2
, "%s and %s are not of compatible types.",
1297 stnode_todisplay(st_arg1
), stnode_todisplay(st_arg2
));
1299 if (!can_func(ftype2
)) {
1300 FAIL(dfw
, st_arg2
, "%s (type=%s) cannot participate in specified comparison.",
1301 stnode_todisplay(st_arg2
), ftype_pretty_name(ftype2
));
1304 else if (type2
== STTYPE_FUNCTION
) {
1305 ftype2
= check_function(dfw
, st_arg2
, ftype1
);
1307 if (!is_bytes_type(ftype2
)) {
1308 if (!ftype_can_slice(ftype2
)) {
1309 FAIL(dfw
, st_arg2
, "Return value of function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
1310 sttype_function_name(st_arg2
),
1311 ftype_pretty_name(ftype2
));
1314 /* Convert function result to bytes */
1315 convert_to_bytes(st_arg2
);
1318 else if (type2
== STTYPE_PCRE
) {
1319 ws_assert(st_op
== STNODE_OP_MATCHES
);
1321 else if (type2
== STTYPE_ARITHMETIC
) {
1322 ftype2
= check_arithmetic(dfw
, st_arg2
, ftype1
);
1324 if (!compatible_ftypes(ftype1
, ftype2
)) {
1325 FAIL(dfw
, st_arg2
, "%s and %s are not of compatible types.",
1326 stnode_todisplay(st_arg1
), stnode_todisplay(st_arg2
));
1329 if (!can_func(ftype2
)) {
1330 FAIL(dfw
, st_arg2
, "%s (type=%s) cannot participate in specified comparison.",
1331 stnode_todisplay(st_arg2
), ftype_pretty_name(ftype2
));
1335 ASSERT_STTYPE_NOT_REACHED(type2
);
1339 /* If the LHS of a relation test is a FUNCTION, run some checks
1340 * and possibly some modifications of syntax tree nodes. */
1342 check_relation_LHS_FUNCTION(dfwork_t
*dfw
, stnode_op_t st_op _U_
,
1343 FtypeCanFunc can_func
, bool allow_partial_value
,
1344 stnode_t
*st_node
, stnode_t
*st_arg1
, stnode_t
*st_arg2
,
1345 ftenum_t logical_ftype
)
1348 ftenum_t ftype1
, ftype2
;
1352 ftype1
= check_function(dfw
, st_arg1
, logical_ftype
);
1353 if (!can_func(ftype1
)) {
1354 FAIL(dfw
, st_arg1
, "Function %s (type=%s) cannot participate in %s comparison.",
1355 sttype_function_name(st_arg1
), ftype_pretty_name(ftype1
),
1356 stnode_todisplay(st_node
));
1359 type2
= stnode_type_id(st_arg2
);
1361 if (IS_FIELD_ENTITY(type2
)) {
1362 ftype2
= sttype_field_ftenum(st_arg2
);
1364 if (!compatible_ftypes(ftype1
, ftype2
)) {
1365 FAIL(dfw
, st_arg2
, "Function %s and %s are not of compatible types.",
1366 sttype_function_name(st_arg1
), stnode_todisplay(st_arg2
));
1368 /* Do this check even though you'd think that if
1369 * they're compatible, then can_func() would pass. */
1370 if (!can_func(ftype2
)) {
1371 FAIL(dfw
, st_arg2
, "%s (type=%s) cannot participate in specified comparison.",
1372 stnode_todisplay(st_arg2
), ftype_pretty_name(ftype2
));
1374 if (type2
== STTYPE_FIELD
) {
1378 else if (type2
== STTYPE_STRING
) {
1379 dfilter_fvalue_from_string(dfw
, ftype1
, st_arg2
, NULL
);
1381 else if (type2
== STTYPE_LITERAL
) {
1382 dfilter_fvalue_from_literal(dfw
, ftype1
, st_arg2
, allow_partial_value
, NULL
);
1384 else if (type2
== STTYPE_CHARCONST
) {
1385 dfilter_fvalue_from_charconst(dfw
, ftype1
, st_arg2
);
1387 else if (type2
== STTYPE_NUMBER
) {
1388 dfilter_fvalue_from_number(dfw
, ftype1
, st_arg2
);
1390 else if (type2
== STTYPE_SLICE
) {
1391 ftype2
= check_slice(dfw
, st_arg2
, ftype1
);
1393 if (!compatible_ftypes(ftype1
, ftype2
)) {
1394 FAIL(dfw
, st_arg2
, "%s and %s are not of compatible types.",
1395 stnode_todisplay(st_arg1
), stnode_todisplay(st_arg2
));
1397 if (!can_func(ftype2
)) {
1398 FAIL(dfw
, st_arg2
, "%s (type=%s) cannot participate in specified comparison.",
1399 stnode_todisplay(st_arg2
), ftype_pretty_name(ftype2
));
1402 if (!is_bytes_type(ftype1
)) {
1403 if (!ftype_can_slice(ftype1
)) {
1404 FAIL(dfw
, st_arg1
, "Function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
1405 sttype_function_name(st_arg1
),
1406 ftype_pretty_name(ftype1
));
1409 /* Convert function result to bytes */
1410 convert_to_bytes(st_arg1
);
1413 else if (type2
== STTYPE_FUNCTION
) {
1414 ftype2
= check_function(dfw
, st_arg2
, ftype1
);
1416 if (!compatible_ftypes(ftype1
, ftype2
)) {
1417 FAIL(dfw
, st_arg2
, "Return values of function %s (type=%s) and function %s (type=%s) are not of compatible types.",
1418 sttype_function_name(st_arg1
), ftype_pretty_name(ftype1
), sttype_function_name(st_arg1
), ftype_pretty_name(ftype2
));
1421 /* Do this check even though you'd think that if
1422 * they're compatible, then can_func() would pass. */
1423 if (!can_func(ftype2
)) {
1424 FAIL(dfw
, st_arg2
, "Return value of %s (type=%s) cannot participate in specified comparison.",
1425 sttype_function_name(st_arg2
), ftype_pretty_name(ftype2
));
1428 else if (type2
== STTYPE_PCRE
) {
1429 ws_assert(st_op
== STNODE_OP_MATCHES
);
1431 else if (type2
== STTYPE_ARITHMETIC
) {
1432 ftype2
= check_arithmetic(dfw
, st_arg2
, ftype1
);
1434 if (!compatible_ftypes(ftype1
, ftype2
)) {
1435 FAIL(dfw
, st_arg2
, "%s and %s are not of compatible types.",
1436 stnode_todisplay(st_arg1
), stnode_todisplay(st_arg2
));
1439 if (!can_func(ftype2
)) {
1440 FAIL(dfw
, st_arg2
, "%s (type=%s) cannot participate in specified comparison.",
1441 stnode_todisplay(st_arg2
), ftype_pretty_name(ftype2
));
1445 ASSERT_STTYPE_NOT_REACHED(type2
);
1450 check_relation_LHS_ARITHMETIC(dfwork_t
*dfw
, stnode_op_t st_op _U_
,
1451 FtypeCanFunc can_func
, bool allow_partial_value
,
1452 stnode_t
*st_node
, stnode_t
*st_arg1
, stnode_t
*st_arg2
,
1453 ftenum_t logical_ftype
)
1456 ftenum_t ftype1
, ftype2
;
1460 ftype1
= check_arithmetic(dfw
, st_arg1
, logical_ftype
);
1461 if (!can_func(ftype1
)) {
1462 FAIL(dfw
, st_arg1
, "Result with type %s cannot participate in %s comparison.",
1463 ftype_pretty_name(ftype1
),
1464 stnode_todisplay(st_node
));
1467 type2
= stnode_type_id(st_arg2
);
1469 if (IS_FIELD_ENTITY(type2
)) {
1470 ftype2
= sttype_field_ftenum(st_arg2
);
1472 if (!compatible_ftypes(ftype1
, ftype2
)) {
1473 FAIL(dfw
, st_arg2
, "%s and %s are not of compatible types.",
1474 stnode_todisplay(st_arg1
), stnode_todisplay(st_arg2
));
1476 if (!can_func(ftype2
)) {
1477 FAIL(dfw
, st_arg2
, "%s (type=%s) cannot participate in specified comparison.",
1478 stnode_todisplay(st_arg2
), ftype_pretty_name(ftype2
));
1480 if (type2
== STTYPE_FIELD
) {
1484 else if (type2
== STTYPE_STRING
) {
1485 dfilter_fvalue_from_string(dfw
, ftype1
, st_arg2
, NULL
);
1487 else if (type2
== STTYPE_LITERAL
) {
1488 dfilter_fvalue_from_literal(dfw
, ftype1
, st_arg2
, allow_partial_value
, NULL
);
1490 else if (type2
== STTYPE_CHARCONST
) {
1491 dfilter_fvalue_from_charconst(dfw
, ftype1
, st_arg2
);
1493 else if (type2
== STTYPE_NUMBER
) {
1494 dfilter_fvalue_from_number(dfw
, ftype1
, st_arg2
);
1496 else if (type2
== STTYPE_SLICE
) {
1497 ftype2
= check_slice(dfw
, st_arg2
, ftype1
);
1499 if (!compatible_ftypes(ftype1
, ftype2
)) {
1500 FAIL(dfw
, st_arg2
, "%s and %s are not of compatible types.",
1501 stnode_todisplay(st_arg1
), stnode_todisplay(st_arg2
));
1503 if (!can_func(ftype2
)) {
1504 FAIL(dfw
, st_arg2
, "%s (type=%s) cannot participate in specified comparison.",
1505 stnode_todisplay(st_arg2
), ftype_pretty_name(ftype2
));
1508 if (!is_bytes_type(ftype1
)) {
1509 if (!ftype_can_slice(ftype1
)) {
1510 FAIL(dfw
, st_arg1
, "Result is a %s and cannot be converted into a sequence of bytes.",
1511 ftype_pretty_name(ftype1
));
1514 /* Convert expression result to bytes */
1515 convert_to_bytes(st_arg1
);
1518 else if (type2
== STTYPE_FUNCTION
) {
1519 ftype2
= check_function(dfw
, st_arg2
, ftype1
);
1521 if (!compatible_ftypes(ftype1
, ftype2
)) {
1522 FAIL(dfw
, st_arg2
, "Result (type=%s) and return value of %s() (type=%s) are not of compatible types.",
1523 ftype_pretty_name(ftype1
),
1524 sttype_function_name(st_arg2
), ftype_pretty_name(ftype2
));
1526 if (!can_func(ftype2
)) {
1527 FAIL(dfw
, st_arg2
, "return value of %s() (type=%s) cannot participate in specified comparison.",
1528 sttype_function_name(st_arg2
), ftype_pretty_name(ftype2
));
1531 else if (type2
== STTYPE_PCRE
) {
1532 ws_assert(st_op
== STNODE_OP_MATCHES
);
1534 else if (type2
== STTYPE_ARITHMETIC
) {
1535 ftype2
= check_arithmetic(dfw
, st_arg2
, ftype1
);
1537 if (!compatible_ftypes(ftype1
, ftype2
)) {
1538 FAIL(dfw
, st_arg2
, "%s and %s are not of compatible types.",
1539 stnode_todisplay(st_arg1
), stnode_todisplay(st_arg2
));
1541 if (!can_func(ftype2
)) {
1542 FAIL(dfw
, st_arg2
, "%s (type=%s) cannot participate in specified comparison.",
1543 stnode_todisplay(st_arg2
), ftype_pretty_name(ftype2
));
1547 ASSERT_STTYPE_NOT_REACHED(type2
);
1551 /* Check the semantics of any relational test. */
1553 check_relation(dfwork_t
*dfw
, stnode_op_t st_op
,
1554 FtypeCanFunc can_func
, bool allow_partial_value
,
1555 stnode_t
*st_node
, stnode_t
*st_arg1
, stnode_t
*st_arg2
)
1557 resolve_unparsed(dfw
, st_arg1
, true);
1558 resolve_unparsed(dfw
, st_arg2
, false);
1562 switch (stnode_type_id(st_arg1
)) {
1564 case STTYPE_REFERENCE
:
1565 case STTYPE_UNPARSED
:
1566 check_relation_LHS_FIELD(dfw
, st_op
, can_func
,
1567 allow_partial_value
, st_node
, st_arg1
, st_arg2
);
1570 check_relation_LHS_SLICE(dfw
, st_op
, can_func
,
1571 allow_partial_value
, st_node
, st_arg1
, st_arg2
, find_logical_ftype(dfw
, st_node
));
1573 case STTYPE_FUNCTION
:
1574 check_relation_LHS_FUNCTION(dfw
, st_op
, can_func
,
1575 allow_partial_value
, st_node
, st_arg1
, st_arg2
, find_logical_ftype(dfw
, st_node
));
1577 case STTYPE_ARITHMETIC
:
1578 check_relation_LHS_ARITHMETIC(dfw
, st_op
, can_func
,
1579 allow_partial_value
, st_node
, st_arg1
, st_arg2
, find_logical_ftype(dfw
, st_node
));
1581 case STTYPE_LITERAL
:
1583 case STTYPE_CHARCONST
:
1585 check_relation_LHS_FVALUE(dfw
, st_op
, can_func
,
1586 allow_partial_value
, st_node
, st_arg1
, st_arg2
, find_logical_ftype(dfw
, st_node
));
1588 case STTYPE_UNINITIALIZED
:
1593 case STTYPE_NUM_TYPES
:
1594 ASSERT_STTYPE_NOT_REACHED(stnode_type_id(st_arg1
));
1599 check_warning_contains_RHS_FIELD(dfwork_t
*dfw
, stnode_t
*st_node _U_
,
1600 stnode_t
*st_arg1 _U_
, stnode_t
*st_arg2
)
1602 const char *token
= stnode_token(st_arg2
);
1603 header_field_info
*hfinfo
= sttype_field_hfinfo(st_arg2
);
1604 fvalue_t
*fvalue
= fvalue_from_literal(FT_BYTES
, token
, true, NULL
);
1605 if (fvalue
!= NULL
) {
1606 char *repr
= fvalue_to_string_repr(dfw
->dfw_scope
, fvalue
, FTREPR_DFILTER
, 0);
1607 add_compile_warning(dfw
, "Interpreting \"%s\" as %s instead of %s. "
1608 "Consider writing \"%s\" or \".%s\" to remove this warning",
1609 token
, hfinfo
->name
, ftype_pretty_name(FT_BYTES
),
1610 repr
, hfinfo
->abbrev
);
1611 fvalue_free(fvalue
);
1616 check_relation_contains(dfwork_t
*dfw
, stnode_t
*st_node
,
1617 stnode_t
*st_arg1
, stnode_t
*st_arg2
)
1619 resolve_unparsed(dfw
, st_arg1
, true);
1620 resolve_unparsed(dfw
, st_arg2
, false);
1624 if (stnode_type_id(st_arg2
) == STTYPE_FIELD
&& stnode_get_flags(st_arg2
, STFLAG_UNPARSED
)) {
1625 check_warning_contains_RHS_FIELD(dfw
, st_node
, st_arg1
, st_arg2
);
1628 switch (stnode_type_id(st_arg1
)) {
1630 case STTYPE_REFERENCE
:
1631 case STTYPE_UNPARSED
:
1632 check_relation_LHS_FIELD(dfw
, STNODE_OP_CONTAINS
, ftype_can_contains
,
1633 true, st_node
, st_arg1
, st_arg2
);
1635 case STTYPE_FUNCTION
:
1636 check_relation_LHS_FUNCTION(dfw
, STNODE_OP_CONTAINS
, ftype_can_contains
,
1637 true, st_node
, st_arg1
, st_arg2
, find_logical_ftype(dfw
, st_node
));
1640 check_relation_LHS_SLICE(dfw
, STNODE_OP_CONTAINS
, ftype_can_contains
,
1641 true, st_node
, st_arg1
, st_arg2
, find_logical_ftype(dfw
, st_node
));
1644 FAIL(dfw
, st_arg1
, "Left side of %s expression must be a field or function, not %s.",
1645 stnode_todisplay(st_node
), stnode_todisplay(st_arg1
));
1651 check_relation_matches(dfwork_t
*dfw
, stnode_t
*st_node
,
1652 stnode_t
*st_arg1
, stnode_t
*st_arg2
)
1655 char *errmsg
= NULL
;
1658 resolve_unparsed(dfw
, st_arg1
, true);
1662 if (stnode_type_id(st_arg2
) != STTYPE_STRING
) {
1663 FAIL(dfw
, st_arg2
, "Matches requires a double quoted string on the right side.");
1666 patt
= stnode_string(st_arg2
);
1667 ws_debug("Compile regex pattern: %s", stnode_token(st_arg2
));
1669 pcre
= ws_regex_compile_ex(patt
->str
, patt
->len
, &errmsg
, WS_REGEX_CASELESS
|WS_REGEX_NEVER_UTF
);
1671 dfilter_fail(dfw
, DF_ERROR_GENERIC
, stnode_location(st_arg2
), "Regex compilation error: %s.", errmsg
);
1673 ws_noisy("Semantic check failed here with a regex syntax error");
1677 stnode_replace(st_arg2
, STTYPE_PCRE
, pcre
);
1679 switch (stnode_type_id(st_arg1
)) {
1681 case STTYPE_REFERENCE
:
1682 check_relation_LHS_FIELD(dfw
, STNODE_OP_MATCHES
, ftype_can_matches
,
1683 true, st_node
, st_arg1
, st_arg2
);
1685 case STTYPE_FUNCTION
:
1686 check_relation_LHS_FUNCTION(dfw
, STNODE_OP_MATCHES
, ftype_can_matches
,
1687 true, st_node
, st_arg1
, st_arg2
, find_logical_ftype(dfw
, st_arg1
));
1690 check_relation_LHS_SLICE(dfw
, STNODE_OP_MATCHES
, ftype_can_matches
,
1691 true, st_node
, st_arg1
, st_arg2
, find_logical_ftype(dfw
, st_arg1
));
1694 FAIL(dfw
, st_arg1
, "Left side of %s expression must be a field or function, not %s.",
1695 stnode_todisplay(st_node
), stnode_todisplay(st_arg1
));
1700 check_relation_in(dfwork_t
*dfw
, stnode_t
*st_node _U_
,
1701 stnode_t
*st_arg1
, stnode_t
*st_arg2
)
1704 stnode_t
*node_left
, *node_right
;
1706 resolve_unparsed(dfw
, st_arg1
, true);
1707 resolve_unparsed(dfw
, st_arg2
, false);
1711 if (stnode_type_id(st_arg1
) != STTYPE_FIELD
) {
1712 FAIL(dfw
, st_arg1
, "Only a field may be tested for membership in a set.");
1714 /* Checked in the grammar parser. */
1715 ws_assert(stnode_type_id(st_arg2
) == STTYPE_SET
);
1717 /* Attempt to interpret one element of the set at a time. Each
1718 * element is represented by two items in the list, the element
1719 * value and NULL. Both will be replaced by a lower and upper
1720 * value if the element is a range. */
1721 nodelist
= stnode_data(st_arg2
);
1723 node_left
= nodelist
->data
;
1724 resolve_unparsed(dfw
, node_left
, false);
1726 /* Don't let a range on the RHS affect the LHS field. */
1727 if (stnode_type_id(node_left
) == STTYPE_SLICE
) {
1728 FAIL(dfw
, node_left
, "A slice may not appear inside a set.");
1732 nodelist
= g_slist_next(nodelist
);
1733 ws_assert(nodelist
);
1734 node_right
= nodelist
->data
;
1736 resolve_unparsed(dfw
, node_right
, false);
1737 check_relation_LHS_FIELD(dfw
, STNODE_OP_GE
, ftype_can_cmp
,
1738 false, st_node
, st_arg1
, node_left
);
1739 check_relation_LHS_FIELD(dfw
, STNODE_OP_LE
, ftype_can_cmp
,
1740 false, st_node
, st_arg1
, node_right
);
1742 check_relation_LHS_FIELD(dfw
, STNODE_OP_ANY_EQ
, ftype_can_eq
,
1743 false, st_node
, st_arg1
, node_left
);
1745 nodelist
= g_slist_next(nodelist
);
1749 /* Check the semantics of any type of TEST */
1751 check_test(dfwork_t
*dfw
, stnode_t
*st_node
)
1754 stnode_t
*st_arg1
, *st_arg2
;
1758 sttype_oper_get(st_node
, &st_op
, &st_arg1
, &st_arg2
);
1762 semcheck(dfw
, st_arg1
);
1766 semcheck(dfw
, st_arg1
);
1767 semcheck(dfw
, st_arg2
);
1769 case STNODE_OP_ALL_EQ
:
1770 case STNODE_OP_ANY_EQ
:
1771 case STNODE_OP_ALL_NE
:
1772 case STNODE_OP_ANY_NE
:
1773 check_relation(dfw
, st_op
, ftype_can_eq
, false, st_node
, st_arg1
, st_arg2
);
1779 check_relation(dfw
, st_op
, ftype_can_cmp
, false, st_node
, st_arg1
, st_arg2
);
1781 case STNODE_OP_CONTAINS
:
1782 check_relation_contains(dfw
, st_node
, st_arg1
, st_arg2
);
1784 case STNODE_OP_MATCHES
:
1785 check_relation_matches(dfw
, st_node
, st_arg1
, st_arg2
);
1788 case STNODE_OP_NOT_IN
:
1789 check_relation_in(dfw
, st_node
, st_arg1
, st_arg2
);
1792 case STNODE_OP_UNINITIALIZED
:
1793 case STNODE_OP_UNARY_MINUS
:
1794 case STNODE_OP_BITWISE_AND
:
1796 case STNODE_OP_SUBTRACT
:
1797 case STNODE_OP_MULTIPLY
:
1798 case STNODE_OP_DIVIDE
:
1799 case STNODE_OP_MODULO
:
1800 ASSERT_STNODE_OP_NOT_REACHED(st_op
);
1805 check_nonzero(dfwork_t
*dfw
, stnode_t
*st_node
)
1811 switch (stnode_type_id(st_node
)) {
1812 case STTYPE_ARITHMETIC
:
1813 ftype
= check_arithmetic(dfw
, st_node
, find_logical_ftype(dfw
, st_node
));
1816 ftype
= check_slice(dfw
, st_node
, find_logical_ftype(dfw
, st_node
));
1818 case STTYPE_FUNCTION
:
1819 ftype
= check_function(dfw
, st_node
, find_logical_ftype(dfw
, st_node
));
1822 ASSERT_STTYPE_NOT_REACHED(stnode_type_id(st_node
));
1825 if (!ftype_can_is_zero(ftype
)) {
1826 FAIL(dfw
, st_node
, "Type %s cannot be assigned a truth value.",
1827 ftype_pretty_name(ftype
));
1834 op_to_error_msg(stnode_op_t st_op
)
1837 case STNODE_OP_UNARY_MINUS
:
1838 return "cannot be negated";
1840 return "cannot be added";
1841 case STNODE_OP_SUBTRACT
:
1842 return "cannot be subtracted";
1843 case STNODE_OP_MULTIPLY
:
1844 return "cannot be multiplied";
1845 case STNODE_OP_DIVIDE
:
1846 return "cannot be divided";
1847 case STNODE_OP_MODULO
:
1848 return "does not support modulo operation";
1849 case STNODE_OP_BITWISE_AND
:
1850 return "does not support bitwise AND";
1852 return "cannot FIXME";
1857 do_unary_minus(dfwork_t
*dfw
, stnode_t
*st_node
, stnode_t
*st_arg1
)
1860 fvalue_t
*new_fv
= fvalue_unary_minus(stnode_data(st_arg1
), &err_msg
);
1862 FAIL_MSG(dfw
, st_node
, err_msg
);
1863 stnode_replace(st_node
, STTYPE_FVALUE
, new_fv
);
1867 do_addition(dfwork_t
*dfw
, stnode_t
*st_node
, stnode_t
*st_arg1
, stnode_t
*st_arg2
)
1870 fvalue_t
*new_fv
= fvalue_add(stnode_data(st_arg1
), stnode_data(st_arg2
), &err_msg
);
1872 FAIL_MSG(dfw
, st_node
, err_msg
);
1873 stnode_replace(st_node
, STTYPE_FVALUE
, new_fv
);
1877 do_subtraction(dfwork_t
*dfw
, stnode_t
*st_node
, stnode_t
*st_arg1
, stnode_t
*st_arg2
)
1880 fvalue_t
*new_fv
= fvalue_subtract(stnode_data(st_arg1
), stnode_data(st_arg2
), &err_msg
);
1882 FAIL_MSG(dfw
, st_node
, err_msg
);
1883 stnode_replace(st_node
, STTYPE_FVALUE
, new_fv
);
1887 do_multiplication(dfwork_t
*dfw
, stnode_t
*st_node
, stnode_t
*st_arg1
, stnode_t
*st_arg2
)
1890 fvalue_t
*new_fv
= fvalue_multiply(stnode_data(st_arg1
), stnode_data(st_arg2
), &err_msg
);
1892 FAIL_MSG(dfw
, st_node
, err_msg
);
1893 stnode_replace(st_node
, STTYPE_FVALUE
, new_fv
);
1897 do_division(dfwork_t
*dfw
, stnode_t
*st_node
, stnode_t
*st_arg1
, stnode_t
*st_arg2
)
1899 if (fvalue_is_zero(stnode_data(st_arg2
)))
1900 FAIL(dfw
, st_node
, "Division by zero");
1903 fvalue_t
*new_fv
= fvalue_divide(stnode_data(st_arg1
), stnode_data(st_arg2
), &err_msg
);
1905 FAIL_MSG(dfw
, st_node
, err_msg
);
1906 stnode_replace(st_node
, STTYPE_FVALUE
, new_fv
);
1910 do_modulo(dfwork_t
*dfw
, stnode_t
*st_node
, stnode_t
*st_arg1
, stnode_t
*st_arg2
)
1912 if (fvalue_is_zero(stnode_data(st_arg2
)))
1913 FAIL(dfw
, st_node
, "Division by zero");
1916 fvalue_t
*new_fv
= fvalue_modulo(stnode_data(st_arg1
), stnode_data(st_arg2
), &err_msg
);
1918 FAIL_MSG(dfw
, st_node
, err_msg
);
1919 stnode_replace(st_node
, STTYPE_FVALUE
, new_fv
);
1923 do_bitwise_and(dfwork_t
*dfw
, stnode_t
*st_node
, stnode_t
*st_arg1
, stnode_t
*st_arg2
)
1926 fvalue_t
*new_fv
= fvalue_bitwise_and(stnode_data(st_arg1
), stnode_data(st_arg2
), &err_msg
);
1928 FAIL_MSG(dfw
, st_node
, err_msg
);
1929 stnode_replace(st_node
, STTYPE_FVALUE
, new_fv
);
1933 check_arithmetic_LHS_NUMBER(dfwork_t
*dfw
, stnode_op_t st_op
,
1934 stnode_t
*st_node
, stnode_t
*st_arg1
, stnode_t
*st_arg2
,
1935 ftenum_t logical_ftype
)
1937 ftenum_t ftype1
, ftype2
;
1938 FtypeCanFunc can_func
= NULL
;
1939 ArithmeticDoFunc do_func
= NULL
;
1943 if (st_op
== STNODE_OP_UNARY_MINUS
) {
1944 ftype1
= check_arithmetic(dfw
, st_arg1
, logical_ftype
);
1945 if (!ftype_can_unary_minus(ftype1
)) {
1946 FAIL(dfw
, st_arg1
, "%s %s.",
1947 ftype_name(ftype1
), op_to_error_msg(st_op
));
1949 if (dfw
->flags
& DF_OPTIMIZE
&& stnode_type_id(st_arg1
) == STTYPE_FVALUE
) {
1950 /* Pre-compute constant result */
1951 do_unary_minus(dfw
, st_node
, st_arg1
);
1958 can_func
= ftype_can_add
;
1959 do_func
= do_addition
;
1961 case STNODE_OP_SUBTRACT
:
1962 can_func
= ftype_can_subtract
;
1963 do_func
= do_subtraction
;
1965 case STNODE_OP_MULTIPLY
:
1966 can_func
= ftype_can_multiply
;
1967 do_func
= do_multiplication
;
1969 case STNODE_OP_DIVIDE
:
1970 can_func
= ftype_can_divide
;
1971 do_func
= do_division
;
1973 case STNODE_OP_MODULO
:
1974 can_func
= ftype_can_modulo
;
1975 do_func
= do_modulo
;
1977 case STNODE_OP_BITWISE_AND
:
1978 can_func
= ftype_can_bitwise_and
;
1979 do_func
= do_bitwise_and
;
1982 ASSERT_STNODE_OP_NOT_REACHED(st_op
);
1985 ftype1
= check_arithmetic(dfw
, st_arg1
, logical_ftype
);
1986 if (!can_func(ftype1
)) {
1987 FAIL(dfw
, st_arg1
, "%s %s.",
1988 ftype_name(ftype1
), op_to_error_msg(st_op
));
1991 ftype2
= check_arithmetic(dfw
, st_arg2
, ftype1
);
1992 if (!can_func(ftype2
)) {
1993 FAIL(dfw
, st_arg2
, "%s %s.",
1994 ftype_name(ftype2
), op_to_error_msg(st_op
));
1997 if (!compatible_ftypes(ftype1
, ftype2
)) {
1998 FAIL(dfw
, st_node
, "%s and %s are not compatible.",
1999 ftype_name(ftype1
), ftype_name(ftype2
));
2002 if (dfw
->flags
& DF_OPTIMIZE
&&
2003 stnode_type_id(st_arg1
) == STTYPE_FVALUE
&&
2004 stnode_type_id(st_arg2
) == STTYPE_FVALUE
) {
2005 /* Pre-compute constant result */
2006 do_func(dfw
, st_node
, st_arg1
, st_arg2
);
2013 * Time arithmetic with scalar multiplication/division only.
2014 * An extra limitation is that multiplicative scalars must appear on the
2018 check_arithmetic_LHS_TIME(dfwork_t
*dfw
, stnode_op_t st_op
, stnode_t
*st_node
,
2019 stnode_t
*st_arg1
, stnode_t
*st_arg2
,
2020 ftenum_t logical_ftype
)
2022 ftenum_t ftype1
, ftype2
;
2023 ArithmeticDoFunc do_func
= NULL
;
2025 sttype_oper_get(st_node
, &st_op
, &st_arg1
, &st_arg2
);
2029 if (st_op
== STNODE_OP_UNARY_MINUS
) {
2030 ftype1
= check_arithmetic(dfw
, st_arg1
, logical_ftype
);
2031 if (dfw
->flags
& DF_OPTIMIZE
&& stnode_type_id(st_arg1
) == STTYPE_FVALUE
) {
2032 do_unary_minus(dfw
, st_node
, st_arg1
);
2039 case STNODE_OP_SUBTRACT
:
2040 ftype1
= check_arithmetic(dfw
, st_arg1
, logical_ftype
);
2041 if (!FT_IS_TIME(ftype1
)) {
2042 FAIL(dfw
, st_node
, "Left hand side must be a time type, not %s.", ftype_pretty_name(ftype1
));
2044 ftype2
= check_arithmetic(dfw
, st_arg2
, logical_ftype
);
2045 if (!FT_IS_TIME(ftype2
)) {
2046 FAIL(dfw
, st_node
, "Right hand side must be a time type, not %s.", ftype_pretty_name(ftype2
));
2049 case STNODE_OP_MULTIPLY
:
2050 case STNODE_OP_DIVIDE
:
2051 ftype1
= check_arithmetic(dfw
, st_arg1
, logical_ftype
);
2052 if (!FT_IS_TIME(ftype1
)) {
2053 FAIL(dfw
, st_node
, "Left hand side must be a time type, not %s.", ftype_pretty_name(ftype1
));
2055 ftype2
= check_arithmetic(dfw
, st_arg2
, FT_SCALAR
);
2056 if (!FT_IS_SCALAR(ftype2
)) {
2057 FAIL(dfw
, st_node
, "Right hand side must be an integer or float type, not %s.", ftype_pretty_name(ftype2
));
2061 FAIL(dfw
, st_node
, "\"%s\" is not a valid arithmetic operator for %s",
2062 stnode_todisplay(st_node
), ftype_pretty_name(logical_ftype
));
2065 if (dfw
->flags
& DF_OPTIMIZE
&&
2066 stnode_type_id(st_arg1
) == STTYPE_FVALUE
&&
2067 stnode_type_id(st_arg2
) == STTYPE_FVALUE
) {
2068 /* Pre-compute constant result */
2071 do_func
= do_addition
;
2073 case STNODE_OP_SUBTRACT
:
2074 do_func
= do_subtraction
;
2076 case STNODE_OP_MULTIPLY
:
2077 do_func
= do_multiplication
;
2079 case STNODE_OP_DIVIDE
:
2080 do_func
= do_division
;
2083 ASSERT_STNODE_OP_NOT_REACHED(st_op
);
2085 do_func(dfw
, st_node
, st_arg1
, st_arg2
);
2092 check_arithmetic(dfwork_t
*dfw
, stnode_t
*st_node
, ftenum_t logical_ftype
)
2096 stnode_t
*st_arg1
, *st_arg2
;
2097 ftenum_t ftype
= FT_NONE
;
2101 resolve_unparsed(dfw
, st_node
, true);
2103 type
= stnode_type_id(st_node
);
2106 case STTYPE_LITERAL
:
2107 dfilter_fvalue_from_literal(dfw
, logical_ftype
, st_node
, false, NULL
);
2108 ftype
= sttype_pointer_ftenum(st_node
);
2112 dfilter_fvalue_from_string(dfw
, logical_ftype
, st_node
, NULL
);
2113 ftype
= sttype_pointer_ftenum(st_node
);
2116 case STTYPE_CHARCONST
:
2117 dfilter_fvalue_from_charconst(dfw
, logical_ftype
, st_node
);
2118 ftype
= sttype_pointer_ftenum(st_node
);
2122 dfilter_fvalue_from_number(dfw
, logical_ftype
, st_node
);
2123 ftype
= sttype_pointer_ftenum(st_node
);
2129 case STTYPE_REFERENCE
:
2130 ftype
= sttype_field_ftenum(st_node
);
2133 case STTYPE_FUNCTION
:
2134 ftype
= check_function(dfw
, st_node
, logical_ftype
);
2138 ftype
= check_slice(dfw
, st_node
, logical_ftype
);
2142 ftype
= sttype_pointer_ftenum(st_node
);
2145 case STTYPE_ARITHMETIC
:
2146 sttype_oper_get(st_node
, &st_op
, &st_arg1
, &st_arg2
);
2147 if (FT_IS_TIME(logical_ftype
))
2148 ftype
= check_arithmetic_LHS_TIME(dfw
, st_op
, st_node
, st_arg1
, st_arg2
, logical_ftype
);
2150 ftype
= check_arithmetic_LHS_NUMBER(dfw
, st_op
, st_node
, st_arg1
, st_arg2
, logical_ftype
);
2155 case STTYPE_UNPARSED
:
2156 case STTYPE_UNINITIALIZED
:
2157 case STTYPE_NUM_TYPES
:
2159 ASSERT_STTYPE_NOT_REACHED(type
);
2166 /* Check the entire syntax tree. */
2168 semcheck(dfwork_t
*dfw
, stnode_t
*st_node
)
2170 /* Does FT_NONE make sense for tests and exists? We don't actually
2171 * return an fvalue in those cases, so, e.g., custom columns have
2172 * check marks, not boolean true/false.
2174 ftenum_t ftype
= FT_NONE
;
2178 dfw
->field_count
= 0;
2180 switch (stnode_type_id(st_node
)) {
2182 check_test(dfw
, st_node
);
2184 case STTYPE_ARITHMETIC
:
2186 case STTYPE_FUNCTION
:
2187 ftype
= check_nonzero(dfw
, st_node
);
2190 ftype
= check_exists(dfw
, st_node
);
2193 if (dfw
->field_count
== 0) {
2194 FAIL(dfw
, st_node
, "Constant expression is invalid.");
2201 /* Check the syntax tree for semantic errors, and convert
2202 * some of the nodes into the form they need to be in order to
2203 * later generate the DFVM bytecode. */
2205 dfw_semcheck(dfwork_t
*dfw
)
2207 volatile bool ok_filter
= true;
2208 volatile ftenum_t ftype
= FT_NONE
;
2210 ws_debug("Starting semantic check (dfw = %p)", dfw
);
2212 /* Instead of having to check for errors at every stage of
2213 * the semantic-checking, the semantic-checking code will
2214 * throw an exception if a problem is found. */
2216 ftype
= semcheck(dfw
, dfw
->st_root
);
2223 ws_debug("Semantic check (dfw = %p) returns %s, return type %s",
2224 dfw
, ok_filter
? "TRUE" : "FALSE", ftype_name(ftype
));
2225 dfw
->ret_type
= ftype
;
2231 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2236 * indent-tabs-mode: t
2239 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2240 * :indentSize=8:tabSize=8:noTabs=false: