regen pidl all: rm epan/dissectors/pidl/*-stamp; pushd epan/dissectors/pidl/ && make...
[wireshark-sm.git] / epan / dfilter / semcheck.c
blobd264f7dd8a7e012227b18761dd16156138719f89
1 /*
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
7 */
9 #include "config.h"
11 #define WS_LOG_DOMAIN LOG_DOMAIN_DFILTER
13 #include <string.h>
15 #include "dfilter-int.h"
16 #include "semcheck.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>
26 #include <epan/tfs.h>
28 #include <wsutil/ws_assert.h>
29 #include <wsutil/wslog.h>
31 #include <ftypes/ftypes.h>
33 #define FAIL(dfw, node, ...) \
34 do { \
35 ws_noisy("Semantic check failed here."); \
36 dfilter_fail_throw(dfw, DF_ERROR_GENERIC, stnode_location(node), __VA_ARGS__); \
37 } while (0)
39 #define FAIL_HERE(dfw) \
40 do { \
41 ws_noisy("Semantic check failed here."); \
42 THROW(TypeError); \
43 } while (0)
45 #define FAIL_MSG(dfw, node, msg) \
46 do { \
47 ws_noisy("Semantic check failed here."); \
48 dfilter_fail(dfw, DF_ERROR_GENERIC, stnode_location(node), \
49 "%s", msg); \
50 g_free(msg); \
51 THROW(TypeError); \
52 } while (0)
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);
62 static ftenum_t
63 find_logical_ftype(dfwork_t *dfw, stnode_t *st_node);
65 static void
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);
70 static ftenum_t
71 semcheck(dfwork_t *dfw, stnode_t *st_node);
73 enum mk_result {
74 MK_ERROR,
75 MK_OK_BOOLEAN,
76 MK_OK_NUMBER,
77 MK_OK_STRING,
80 static enum mk_result
81 mk_fvalue_from_val_string(dfwork_t *dfw, header_field_info *hfinfo, const char *s, stnode_t *st);
83 static inline bool
84 op_is_equality(stnode_op_t op)
86 switch (op) {
87 case STNODE_OP_ALL_EQ:
88 case STNODE_OP_ANY_EQ:
89 case STNODE_OP_ALL_NE:
90 case STNODE_OP_ANY_NE:
91 case STNODE_OP_IN:
92 case STNODE_OP_NOT_IN:
93 return true;
94 default:
95 return false;
99 /* Compares to ftenum_t's and decides if they're
100 * compatible or not (if they're the same basic type) */
101 bool
102 compatible_ftypes(ftenum_t a, ftenum_t b)
104 switch (a) {
105 case FT_NONE:
106 case FT_BOOLEAN:
107 case FT_PROTOCOL:
108 case FT_ABSOLUTE_TIME: /* XXX - README.dissector says the time types are compatible */
109 case FT_RELATIVE_TIME:
110 case FT_IEEE_11073_SFLOAT: /* XXX - should be able to compare with DOUBLE (#19011) */
111 case FT_IEEE_11073_FLOAT: /* XXX - should be able to compare with DOUBLE */
112 case FT_IPv4:
113 case FT_IPv6:
114 case FT_GUID:
115 return a == b;
117 case FT_FLOAT: /* XXX - should be able to compare with INT */
118 case FT_DOUBLE: /* XXX - should be able to compare with INT */
119 switch (b) {
120 case FT_FLOAT:
121 case FT_DOUBLE:
122 return true;
123 default:
124 return false;
127 case FT_ETHER:
128 case FT_BYTES:
129 case FT_UINT_BYTES:
130 case FT_OID:
131 case FT_VINES:
132 case FT_FCWWN:
133 case FT_REL_OID:
134 case FT_SYSTEM_ID:
136 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);
138 case FT_UINT8:
139 case FT_UINT16:
140 case FT_UINT24:
141 case FT_UINT32:
142 case FT_CHAR:
143 case FT_FRAMENUM:
144 case FT_IPXNET:
145 return ftype_can_val_to_uinteger(b);
147 case FT_UINT40:
148 case FT_UINT48:
149 case FT_UINT56:
150 case FT_UINT64:
151 case FT_EUI64:
152 return ftype_can_val_to_uinteger64(b);
154 case FT_INT8:
155 case FT_INT16:
156 case FT_INT24:
157 case FT_INT32:
158 return ftype_can_val_to_sinteger(b);
160 case FT_INT40:
161 case FT_INT48:
162 case FT_INT56:
163 case FT_INT64:
164 return ftype_can_val_to_sinteger64(b);
166 case FT_STRING:
167 case FT_STRINGZ:
168 case FT_UINT_STRING:
169 case FT_STRINGZPAD:
170 case FT_STRINGZTRUNC:
171 case FT_AX25:
172 return FT_IS_STRING(b);
174 case FT_NUM_TYPES:
175 case FT_SCALAR:
176 ASSERT_FTYPE_NOT_REACHED(a);
179 ws_assert_not_reached();
180 return false;
183 void
184 resolve_unparsed(dfwork_t *dfw, stnode_t *st, bool strict)
186 if (stnode_type_id(st) != STTYPE_UNPARSED)
187 return;
189 header_field_info *hfinfo = dfilter_resolve_unparsed(stnode_data(st), dfw->deprecated);
190 if (hfinfo != NULL)
191 stnode_replace(st, STTYPE_FIELD, hfinfo);
192 else if (strict)
193 FAIL(dfw, st, "\"%s\" is not a valid protocol or protocol field.", stnode_todisplay(st));
194 else
195 stnode_mutate(st, STTYPE_LITERAL);
198 /* Don't set the error message if it's already set. */
199 #define SET_ERROR(dfw, str) \
200 do { \
201 if ((str) != NULL && (dfw)->error == NULL) { \
202 (dfw)->error = df_error_new(DF_ERROR_GENERIC, str, NULL); \
204 else { \
205 g_free(str); \
207 } while (0)
209 /* Transforms a syntax node into a value and sets the error message on failure. */
210 bool
211 dfilter_fvalue_from_literal(dfwork_t *dfw, ftenum_t ftype, stnode_t *st,
212 bool allow_partial_value, header_field_info *hfinfo_value_string)
214 fvalue_t *fv;
215 const char *s = stnode_data(st);
216 char *error_message = NULL;
217 enum mk_result res;
219 fv = fvalue_from_literal(ftype, s, allow_partial_value, &error_message);
220 if (fv != NULL) {
221 g_free(error_message); // error_message is expected to be null
222 stnode_replace(st, STTYPE_FVALUE, fv);
223 return false;
225 SET_ERROR(dfw, error_message);
227 if (hfinfo_value_string) {
228 /* check value_string */
229 res = mk_fvalue_from_val_string(dfw, hfinfo_value_string, s, st);
231 * Ignore previous errors if this can be mapped
232 * to an item from value_string.
234 if (res != MK_ERROR) {
235 df_error_free(&dfw->error);
236 add_compile_warning(dfw, "Interpreting the symbol \u2039%s\u203A as a %s value string. "
237 "Writing value strings without double quotes is deprecated. "
238 "Please use \u2039\"%s\"\u203A instead",
239 stnode_token(st), ftype_pretty_name(hfinfo_value_string->type), stnode_token(st));
240 return res == MK_OK_STRING;
244 // Failure
245 dfw_set_error_location(dfw, stnode_location(st));
246 FAIL_HERE(dfw);
247 ws_assert_not_reached();
250 /* Transforms a syntax node into a value and sets the error message on failure. */
251 bool
252 dfilter_fvalue_from_string(dfwork_t *dfw, ftenum_t ftype, stnode_t *st,
253 header_field_info *hfinfo_value_string)
255 fvalue_t *fv;
256 const GString *gs = stnode_string(st);
257 char *error_message = NULL;
258 enum mk_result res;
260 fv = fvalue_from_string(ftype, gs->str, gs->len, &error_message);
261 if (fv != NULL) {
262 g_free(error_message); // error_message is expected to be null
263 stnode_replace(st, STTYPE_FVALUE, fv);
264 return false;
266 SET_ERROR(dfw, error_message);
268 if (hfinfo_value_string) {
269 res = mk_fvalue_from_val_string(dfw, hfinfo_value_string, gs->str, st);
271 * Ignore previous errors if this can be mapped
272 * to an item from value_string.
274 if (res != MK_ERROR) {
275 df_error_free(&dfw->error);
276 return res == MK_OK_STRING;
280 // Failure
281 dfw_set_error_location(dfw, stnode_location(st));
282 FAIL_HERE(dfw);
283 ws_assert_not_reached();
286 void
287 dfilter_fvalue_from_charconst(dfwork_t *dfw, ftenum_t ftype, stnode_t *st)
289 fvalue_t *fv;
290 unsigned long *nump = stnode_data(st);
291 char *error_message = NULL;
293 fv = fvalue_from_charconst(ftype, *nump, &error_message);
294 if (fv != NULL) {
295 g_free(error_message); // error_message is expected to be null
296 stnode_replace(st, STTYPE_FVALUE, fv);
297 return;
299 SET_ERROR(dfw, error_message);
301 // Failure
302 dfw_set_error_location(dfw, stnode_location(st));
303 FAIL_HERE(dfw);
304 ws_assert_not_reached();
307 void
308 dfilter_fvalue_from_number(dfwork_t *dfw, ftenum_t ftype, stnode_t *st)
310 fvalue_t *fv = NULL;
311 const char *s = stnode_token(st);
312 char *error_message = NULL;
313 stnumber_t num_type;
315 num_type = sttype_number_get_type(st);
317 if (ftype == FT_SCALAR) {
318 /* If a scalar was requested then transform the number
319 * syntax node to an fvalue according to its lexical
320 * type (integer or float). */
321 switch (num_type) {
322 case STNUM_INTEGER:
323 case STNUM_UNSIGNED:
324 ftype = FT_INT64;
325 break;
326 case STNUM_FLOAT:
327 ftype = FT_DOUBLE;
328 break;
329 case STNUM_NONE:
330 ws_assert_not_reached();
334 switch (num_type) {
335 case STNUM_INTEGER:
336 fv = fvalue_from_sinteger64(ftype, s, sttype_number_get_integer(st), &error_message);
337 break;
339 case STNUM_UNSIGNED:
340 fv = fvalue_from_uinteger64(ftype, s, sttype_number_get_unsigned(st), &error_message);
341 break;
343 case STNUM_FLOAT:
344 fv = fvalue_from_floating(ftype, s, sttype_number_get_float(st), &error_message);
345 break;
347 case STNUM_NONE:
348 ws_assert_not_reached();
351 if (fv != NULL) {
352 g_free(error_message); // error_message is expected to be null
353 stnode_replace(st, STTYPE_FVALUE, fv);
354 return;
356 SET_ERROR(dfw, error_message);
358 // Failure
359 dfw_set_error_location(dfw, stnode_location(st));
360 FAIL_HERE(dfw);
361 ws_assert_not_reached();
364 /* Creates a FT_BOOLEAN fvalue with a given value. */
365 static fvalue_t*
366 mk_boolean_fvalue(bool val)
368 fvalue_t *fv;
370 fv = fvalue_new(FT_BOOLEAN);
371 fvalue_set_uinteger64(fv, val);
373 return fv;
376 /* Creates a FT_STRING fvalue with a given value. */
377 static fvalue_t*
378 mk_string_fvalue(const char *str)
380 fvalue_t *fv = fvalue_new(FT_STRING);
381 fvalue_set_string(fv, str);
382 return fv;
385 /* Creates a FT_UINT64 fvalue with a given value. */
386 static fvalue_t*
387 mk_uint64_fvalue(uint64_t val)
389 fvalue_t *fv = fvalue_new(FT_UINT64);
390 fvalue_set_uinteger64(fv, val);
391 return fv;
394 /* Try to make an fvalue from a string using a value_string or true_false_string.
395 * This works only for ftypes that are integers. Returns the created fvalue_t*
396 * or NULL if impossible.
397 * If the mapping number<->string is unique convert the string to a number
398 * by inverting the value string function.
399 * Otherwise we compile it as a string and map the field value at runtime
400 * to a string for the comparison.
402 * XXX - This should check all hfinfo with the same abbreviation, not just the
403 * last registered. If there are multiple fields registered, then all the fields
404 * must map the same number (and only that number) to the string in order for
405 * optimizing into a number test to be valid (see #19111). Otherwise, we should
406 * allow the string match if it at least one field with the same abbreviation has
407 * a value string with that string as an entry.
409 static enum mk_result
410 mk_fvalue_from_val_string(dfwork_t *dfw, header_field_info *hfinfo, const char *s, stnode_t *st)
412 /* Early return? */
413 switch(hfinfo->type) {
414 case FT_NONE:
415 case FT_PROTOCOL: /* hfinfo->strings contains the protocol_t */
416 case FT_FLOAT:
417 case FT_DOUBLE:
418 case FT_IEEE_11073_SFLOAT:
419 case FT_IEEE_11073_FLOAT:
420 case FT_ABSOLUTE_TIME:
421 case FT_RELATIVE_TIME:
422 case FT_IPv4:
423 case FT_IPv6:
424 case FT_IPXNET:
425 case FT_AX25:
426 case FT_VINES:
427 case FT_FCWWN:
428 case FT_ETHER:
429 case FT_BYTES:
430 case FT_UINT_BYTES:
431 case FT_STRING:
432 case FT_STRINGZ:
433 case FT_UINT_STRING:
434 case FT_STRINGZPAD:
435 case FT_STRINGZTRUNC:
436 case FT_EUI64:
437 case FT_GUID:
438 case FT_OID:
439 case FT_REL_OID:
440 case FT_SYSTEM_ID:
441 case FT_FRAMENUM: /* hfinfo->strings contains ft_framenum_type_t, not strings */
442 return MK_ERROR;
444 case FT_BOOLEAN:
445 case FT_CHAR:
446 case FT_UINT8:
447 case FT_UINT16:
448 case FT_UINT24:
449 case FT_UINT32:
450 case FT_UINT40:
451 case FT_UINT48:
452 case FT_UINT56:
453 case FT_UINT64:
454 case FT_INT8:
455 case FT_INT16:
456 case FT_INT24:
457 case FT_INT32:
458 case FT_INT40:
459 case FT_INT48:
460 case FT_INT56:
461 case FT_INT64:
462 break;
464 case FT_NUM_TYPES:
465 case FT_SCALAR:
466 ASSERT_FTYPE_NOT_REACHED(hfinfo->type);
469 /* Do val_strings exist? */
470 if (!hfinfo->strings) {
471 dfilter_fail(dfw, DF_ERROR_GENERIC, stnode_location(st), "%s cannot accept strings as values.",
472 hfinfo->abbrev);
473 return MK_ERROR;
476 /* Reset the error message, since *something* interesting will happen,
477 * and the error message will be more interesting than any error message
478 * I happen to have now. */
479 df_error_free(&dfw->error);
481 fvalue_t *fv;
482 uint64_t val = 0, val_max = 0;
483 size_t count = 0;
485 if (hfinfo->type == FT_BOOLEAN) {
486 const true_false_string *tf = (const true_false_string *)hfinfo->strings;
488 if (g_ascii_strcasecmp(s, tf->true_string) == 0) {
489 fv = mk_boolean_fvalue(true);
490 stnode_replace(st, STTYPE_FVALUE, fv);
491 return MK_OK_BOOLEAN;
493 if (g_ascii_strcasecmp(s, tf->false_string) == 0) {
494 fv = mk_boolean_fvalue(false);
495 stnode_replace(st, STTYPE_FVALUE, fv);
496 return MK_OK_BOOLEAN;
498 dfilter_fail(dfw, DF_ERROR_GENERIC, stnode_location(st), "\"%s\" cannot be found among the possible values for %s.",
499 s, hfinfo->abbrev);
501 else if (hfinfo->display & BASE_RANGE_STRING) {
502 const range_string *vals = (const range_string *)hfinfo->strings;
504 while (vals->strptr != NULL && count <= 1) {
505 if (g_ascii_strcasecmp(s, vals->strptr) == 0) {
506 val = vals->value_min;
507 val_max = vals->value_max;
508 count++;
510 vals++;
512 if (count > 1) {
513 // More than one match, use a string.
514 fv = mk_string_fvalue(s);
515 stnode_replace(st, STTYPE_FVALUE, fv);
516 return MK_OK_STRING;
518 else if (count == 1) {
519 // If the range has a single value use an integer.
520 // Otherwise use a string.
521 if (val == val_max) {
522 fv = mk_uint64_fvalue(val);
523 stnode_replace(st, STTYPE_FVALUE, fv);
524 return MK_OK_NUMBER;
526 else {
527 fv = mk_string_fvalue(s);
528 stnode_replace(st, STTYPE_FVALUE, fv);
529 return MK_OK_STRING;
532 else {
533 dfilter_fail(dfw, DF_ERROR_GENERIC, stnode_location(st), "\"%s\" cannot be found among the possible values for %s.",
534 s, hfinfo->abbrev);
537 else if (hfinfo->display & BASE_VAL64_STRING) {
538 const val64_string *vals = (const val64_string *)hfinfo->strings;
539 if (hfinfo->display & BASE_EXT_STRING)
540 vals = VAL64_STRING_EXT_VS_P((const val64_string_ext *) vals);
542 while (vals->strptr != NULL && count <= 1) {
543 if (g_ascii_strcasecmp(s, vals->strptr) == 0) {
544 val = vals->value;
545 count++;
547 vals++;
549 if (count > 1) {
550 // More than one match, use a string.
551 fv = mk_string_fvalue(s);
552 stnode_replace(st, STTYPE_FVALUE, fv);
553 return MK_OK_STRING;
555 else if (count == 1) {
556 // Only one match, convert string to number.
557 fv = mk_uint64_fvalue(val);
558 stnode_replace(st, STTYPE_FVALUE, fv);
559 return MK_OK_NUMBER;
561 else {
562 dfilter_fail(dfw, DF_ERROR_GENERIC, stnode_location(st), "\"%s\" cannot be found among the possible values for %s.",
563 s, hfinfo->abbrev);
566 else if (hfinfo->display == BASE_CUSTOM) {
567 /* We don't have a string catalog to compare to so just assume
568 * the provided string is a valid custom representation. */
569 if (FT_IS_INTEGER(hfinfo->type)) {
570 fv = mk_string_fvalue(s);
571 stnode_replace(st, STTYPE_FVALUE, fv);
572 return MK_OK_STRING;
574 dfilter_fail(dfw, DF_ERROR_GENERIC, stnode_location(st), "%s must be an integer.", hfinfo->abbrev);
576 else {
577 const value_string *vals = (const value_string *)hfinfo->strings;
578 if (hfinfo->display & BASE_EXT_STRING)
579 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *) vals);
581 while (vals->strptr != NULL && count <= 1) {
582 if (g_ascii_strcasecmp(s, vals->strptr) == 0) {
583 val = vals->value;
584 count++;
586 vals++;
588 if (count > 1) {
589 // More than one match, use a string.
590 fv = mk_string_fvalue(s);
591 stnode_replace(st, STTYPE_FVALUE, fv);
592 return MK_OK_STRING;
594 else if (count == 1) {
595 // Only one match, convert string to number.
596 fv = mk_uint64_fvalue(val);
597 stnode_replace(st, STTYPE_FVALUE, fv);
598 return MK_OK_NUMBER;
600 else {
601 dfilter_fail(dfw, DF_ERROR_GENERIC, stnode_location(st), "\"%s\" cannot be found among the possible values for %s.",
602 s, hfinfo->abbrev);
605 return MK_ERROR;
608 static bool
609 is_bytes_type(enum ftenum type)
611 switch(type) {
612 case FT_VINES:
613 case FT_FCWWN:
614 case FT_ETHER:
615 case FT_BYTES:
616 case FT_UINT_BYTES:
617 case FT_IPv6:
618 case FT_OID:
619 case FT_REL_OID:
620 case FT_SYSTEM_ID:
621 return true;
623 case FT_NONE:
624 case FT_PROTOCOL:
625 case FT_FLOAT:
626 case FT_DOUBLE:
627 case FT_IEEE_11073_SFLOAT:
628 case FT_IEEE_11073_FLOAT:
629 case FT_ABSOLUTE_TIME:
630 case FT_RELATIVE_TIME:
631 case FT_IPv4:
632 case FT_IPXNET:
633 case FT_GUID:
634 case FT_STRING:
635 case FT_STRINGZ:
636 case FT_UINT_STRING:
637 case FT_STRINGZPAD:
638 case FT_STRINGZTRUNC:
639 case FT_AX25:
640 case FT_BOOLEAN:
641 case FT_FRAMENUM:
642 case FT_CHAR:
643 case FT_UINT8:
644 case FT_UINT16:
645 case FT_UINT24:
646 case FT_UINT32:
647 case FT_UINT40:
648 case FT_UINT48:
649 case FT_UINT56:
650 case FT_UINT64:
651 case FT_INT8:
652 case FT_INT16:
653 case FT_INT24:
654 case FT_INT32:
655 case FT_INT40:
656 case FT_INT48:
657 case FT_INT56:
658 case FT_INT64:
659 case FT_EUI64:
660 return false;
662 case FT_NUM_TYPES:
663 case FT_SCALAR:
664 ASSERT_FTYPE_NOT_REACHED(type);
667 ws_assert_not_reached();
668 return false;
671 static ftenum_t
672 get_slice_ftype(dfwork_t *dfw, stnode_t *st_node)
674 stnode_t *entity1 = sttype_slice_entity(st_node);
675 ws_assert(entity1);
676 resolve_unparsed(dfw, entity1, true);
677 ftenum_t ftype = get_logical_ftype(dfw, entity1);
678 return FT_IS_STRING(ftype) ? FT_STRING : FT_BYTES;
681 static ftenum_t
682 get_function_ftype(dfwork_t *dfw, stnode_t *st_node)
684 df_func_def_t *funcdef;
685 GSList *params;
686 unsigned nparams;
688 funcdef = sttype_function_funcdef(st_node);
689 params = sttype_function_params(st_node);
690 nparams = g_slist_length(params);
692 if (funcdef->return_ftype != FT_NONE)
693 return funcdef->return_ftype;
694 if (nparams < 1)
695 return FT_NONE;
697 for (GSList *l = params; l != NULL; l = l->next) {
698 resolve_unparsed(dfw, l->data, false);
699 ftenum_t ftype = get_logical_ftype(dfw, l->data);
700 if (ftype != FT_NONE) {
701 return ftype;
704 return FT_NONE;
707 ftenum_t
708 get_logical_ftype(dfwork_t *dfw, stnode_t *st_node)
710 stnode_t *st_arg1, *st_arg2;
711 ftenum_t ft;
713 switch(stnode_type_id(st_node)) {
714 case STTYPE_FIELD:
715 case STTYPE_REFERENCE:
716 return sttype_field_ftenum(st_node);
718 case STTYPE_UNPARSED:
719 resolve_unparsed(dfw, st_node, true);
720 return sttype_field_ftenum(st_node);
722 case STTYPE_STRING:
723 case STTYPE_LITERAL:
724 case STTYPE_CHARCONST:
725 case STTYPE_NUMBER:
726 return FT_NONE;
728 case STTYPE_FUNCTION:
729 return get_function_ftype(dfw, st_node);
731 case STTYPE_ARITHMETIC:
732 case STTYPE_TEST:
733 sttype_oper_get(st_node, NULL, &st_arg1, &st_arg2);
734 if (st_arg1 && (ft = get_logical_ftype(dfw, st_arg1)) != FT_NONE)
735 return ft;
736 if (st_arg2 && (ft = get_logical_ftype(dfw, st_arg2)) != FT_NONE)
737 return ft;
738 return FT_NONE;
740 case STTYPE_SLICE:
741 return get_slice_ftype(dfw, st_node);
743 case STTYPE_SET:
744 case STTYPE_UNINITIALIZED:
745 case STTYPE_NUM_TYPES:
746 case STTYPE_FVALUE:
747 case STTYPE_PCRE:
748 ASSERT_STTYPE_NOT_REACHED(stnode_type_id(st_node));
751 ws_assert_not_reached();
754 static ftenum_t
755 find_logical_ftype(dfwork_t *dfw, stnode_t *st_node)
757 ftenum_t ftype = get_logical_ftype(dfw, st_node);
758 if (ftype == FT_NONE) {
759 FAIL(dfw, st_node, "Constant expression is invalid");
761 return ftype;
764 /* Check the semantics of an existence test. */
765 static ftenum_t
766 check_exists(dfwork_t *dfw, stnode_t *st_arg1)
768 ftenum_t ftype = FT_NONE;
769 resolve_unparsed(dfw, st_arg1, true);
771 LOG_NODE(st_arg1);
773 switch (stnode_type_id(st_arg1)) {
774 case STTYPE_FIELD:
775 dfw->field_count++;
776 /* fall-through */
777 case STTYPE_REFERENCE:
778 /* This is OK */
779 if (dfw->flags & DF_RETURN_VALUES) {
780 ftype = sttype_field_ftenum(st_arg1);
782 break;
783 case STTYPE_STRING:
784 case STTYPE_LITERAL:
785 case STTYPE_CHARCONST:
786 case STTYPE_NUMBER:
787 FAIL(dfw, st_arg1, "%s is neither a field nor a protocol name.",
788 stnode_todisplay(st_arg1));
789 break;
791 case STTYPE_UNPARSED:
792 case STTYPE_FUNCTION:
793 case STTYPE_SET:
794 case STTYPE_UNINITIALIZED:
795 case STTYPE_NUM_TYPES:
796 case STTYPE_TEST:
797 case STTYPE_FVALUE:
798 case STTYPE_PCRE:
799 case STTYPE_ARITHMETIC:
800 case STTYPE_SLICE:
801 ASSERT_STTYPE_NOT_REACHED(stnode_type_id(st_arg1));
804 return ftype;
807 ftenum_t
808 check_slice(dfwork_t *dfw, stnode_t *st, ftenum_t logical_ftype)
810 stnode_t *entity1;
811 header_field_info *hfinfo1;
812 sttype_id_t sttype1;
813 ftenum_t ftype1 = FT_NONE;
815 LOG_NODE(st);
817 entity1 = sttype_slice_entity(st);
818 ws_assert(entity1);
819 resolve_unparsed(dfw, entity1, true);
820 sttype1 = stnode_type_id(entity1);
822 switch (sttype1) {
823 case STTYPE_FIELD:
824 dfw->field_count++;
825 /* fall-through */
826 case STTYPE_REFERENCE:
827 hfinfo1 = sttype_field_hfinfo(entity1);
828 ftype1 = sttype_field_ftenum(entity1);
830 if (!ftype_can_slice(ftype1)) {
831 FAIL(dfw, entity1, "\"%s\" is a %s and cannot be sliced into a sequence of bytes.",
832 hfinfo1->abbrev, ftype_pretty_name(ftype1));
834 break;
836 case STTYPE_FUNCTION:
837 ftype1 = check_function(dfw, entity1, logical_ftype);
839 if (!ftype_can_slice(ftype1)) {
840 FAIL(dfw, entity1, "Return value of function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
841 sttype_function_name(entity1), ftype_pretty_name(ftype1));
843 break;
845 case STTYPE_SLICE:
846 ftype1 = check_slice(dfw, entity1, logical_ftype);
847 break;
849 case STTYPE_LITERAL:
850 case STTYPE_STRING:
851 case STTYPE_CHARCONST:
852 case STTYPE_NUMBER:
853 FAIL(dfw, entity1, "Range is not supported for entity %s",
854 stnode_todisplay(entity1));
856 case STTYPE_UNPARSED:
857 case STTYPE_UNINITIALIZED:
858 case STTYPE_NUM_TYPES:
859 case STTYPE_PCRE:
860 case STTYPE_FVALUE:
861 case STTYPE_TEST:
862 case STTYPE_ARITHMETIC:
863 case STTYPE_SET:
864 ASSERT_STTYPE_NOT_REACHED(sttype1);
868 return FT_IS_STRING(ftype1) ? FT_STRING : FT_BYTES;
871 static void
872 convert_to_bytes(stnode_t *arg)
874 stnode_t *entity1;
875 drange_node *rn;
877 entity1 = stnode_dup(arg);
878 rn = drange_node_new();
879 drange_node_set_start_offset(rn, 0);
880 drange_node_set_to_the_end(rn);
882 stnode_replace(arg, STTYPE_SLICE, NULL);
883 sttype_slice_set1(arg, entity1, rn);
886 ftenum_t
887 check_function(dfwork_t *dfw, stnode_t *st_node, ftenum_t logical_ftype)
889 df_func_def_t *funcdef;
890 GSList *params;
891 unsigned nparams;
893 LOG_NODE(st_node);
895 funcdef = sttype_function_funcdef(st_node);
896 params = sttype_function_params(st_node);
897 nparams = g_slist_length(params);
899 if (nparams < funcdef->min_nargs) {
900 FAIL(dfw, st_node, "Function %s needs at least %u arguments.",
901 funcdef->name, funcdef->min_nargs);
902 } else if (funcdef->max_nargs > 0 && nparams > funcdef->max_nargs) {
903 FAIL(dfw, st_node, "Function %s can only accept %u arguments.",
904 funcdef->name, funcdef->max_nargs);
907 return funcdef->semcheck_param_function(dfw, funcdef->name, logical_ftype, params,
908 stnode_location(st_node));
911 /* If the LHS of a relation test is a FIELD, run some checks
912 * and possibly some modifications of syntax tree nodes. */
913 static void
914 check_relation_LHS_FIELD(dfwork_t *dfw, stnode_op_t st_op,
915 FtypeCanFunc can_func, bool allow_partial_value,
916 stnode_t *st_node,
917 stnode_t *st_arg1, stnode_t *st_arg2)
919 sttype_id_t type2;
920 header_field_info *hfinfo1;
921 ftenum_t ftype1, ftype2;
922 bool mk_val_string = false;
924 LOG_NODE(st_node);
926 if (stnode_type_id(st_arg1) == STTYPE_FIELD)
927 dfw->field_count++;
929 hfinfo1 = sttype_field_hfinfo(st_arg1);
930 ftype1 = sttype_field_ftenum(st_arg1);
931 if (!can_func(ftype1)) {
932 /* For "matches", implicitly convert to the value string, if
933 * there is one. (FT_FRAMENUM and FT_PROTOCOL have a pointer
934 * to something other than a value string in their ->strings
935 * member, though we can't get here for a FT_PROTOCOL because
936 * it supports "matches" on its bytes without conversion.)
938 if (st_op == STNODE_OP_MATCHES && hfinfo1->strings != NULL && hfinfo1->type != FT_FRAMENUM && hfinfo1->type != FT_PROTOCOL) {
939 sttype_field_set_value_string(st_arg1, true);
941 else {
942 FAIL(dfw, st_arg1, "%s (type=%s) cannot participate in %s comparison.",
943 hfinfo1->abbrev, ftype_pretty_name(ftype1),
944 stnode_todisplay(st_node));
948 ftype1 = sttype_field_ftenum(st_arg1);
949 type2 = stnode_type_id(st_arg2);
951 if (IS_FIELD_ENTITY(type2)) {
952 ftype2 = sttype_field_ftenum(st_arg2);
954 if (!compatible_ftypes(ftype1, ftype2)) {
955 FAIL(dfw, st_arg2, "%s and %s are not of compatible types.",
956 stnode_todisplay(st_arg1), stnode_todisplay(st_arg2));
958 /* Do this check even though you'd think that if
959 * they're compatible, then can_func() would pass. */
960 if (!can_func(ftype2)) {
961 FAIL(dfw, st_arg2, "%s (type=%s) cannot participate in specified comparison.",
962 stnode_todisplay(st_arg2), ftype_pretty_name(ftype2));
964 if (type2 == STTYPE_FIELD) {
965 dfw->field_count++;
968 else if (type2 == STTYPE_STRING || type2 == STTYPE_LITERAL) {
970 /* Skip incompatible fields */
971 while (hfinfo1->same_name_prev_id != -1 &&
972 ((type2 == STTYPE_STRING && ftype1 != FT_STRING && ftype1!= FT_STRINGZ) ||
973 (type2 != STTYPE_STRING && (ftype1 == FT_STRING || ftype1== FT_STRINGZ)))) {
974 hfinfo1 = proto_registrar_get_nth(hfinfo1->same_name_prev_id);
975 ftype1 = hfinfo1->type;
978 if (type2 == STTYPE_STRING) {
979 mk_val_string = dfilter_fvalue_from_string(dfw, ftype1, st_arg2, hfinfo1);
981 else {
982 mk_val_string = dfilter_fvalue_from_literal(dfw, ftype1, st_arg2, allow_partial_value, hfinfo1);
984 if (mk_val_string) {
985 sttype_field_set_value_string(st_arg1, true);
986 // Value strings can only be ordered if they are numerical.
987 // Don't try to order them lexicographically, that's not
988 // what users expect.
989 if (!op_is_equality(st_op)) {
990 FAIL(dfw, st_arg2, "Cannot use order comparisons with \"%s\" "
991 "because the value string cannot be uniquely converted to an integer.",
992 stnode_todisplay(st_arg2));
996 else if (type2 == STTYPE_CHARCONST) {
997 dfilter_fvalue_from_charconst(dfw, ftype1, st_arg2);
999 else if (type2 == STTYPE_NUMBER) {
1000 dfilter_fvalue_from_number(dfw, ftype1, st_arg2);
1002 else if (type2 == STTYPE_SLICE) {
1003 ftype2 = check_slice(dfw, st_arg2, ftype1);
1005 if (!compatible_ftypes(ftype1, ftype2)) {
1006 FAIL(dfw, st_arg2, "%s and %s are not of compatible types.",
1007 stnode_todisplay(st_arg1), stnode_todisplay(st_arg2));
1009 if (!can_func(ftype2)) {
1010 FAIL(dfw, st_arg2, "%s (type=%s) cannot participate in specified comparison.",
1011 stnode_todisplay(st_arg2), ftype_pretty_name(ftype2));
1014 if (!is_bytes_type(ftype1)) {
1015 if (!ftype_can_slice(ftype1)) {
1016 FAIL(dfw, st_arg1, "\"%s\" is a %s and cannot be converted into a sequence of bytes.",
1017 hfinfo1->abbrev,
1018 ftype_pretty_name(ftype1));
1021 /* Convert entire field to bytes */
1022 convert_to_bytes(st_arg1);
1025 else if (type2 == STTYPE_FUNCTION) {
1026 ftype2 = check_function(dfw, st_arg2, ftype1);
1028 if (!compatible_ftypes(ftype1, ftype2)) {
1029 FAIL(dfw, st_arg2, "%s (type=%s) and return value of %s() (type=%s) are not of compatible types.",
1030 hfinfo1->abbrev, ftype_pretty_name(ftype1),
1031 sttype_function_name(st_arg2), ftype_pretty_name(ftype2));
1034 if (!can_func(ftype2)) {
1035 FAIL(dfw, st_arg2, "return value of %s() (type=%s) cannot participate in specified comparison.",
1036 sttype_function_name(st_arg2), ftype_pretty_name(ftype2));
1039 else if (type2 == STTYPE_PCRE) {
1040 ws_assert(st_op == STNODE_OP_MATCHES);
1042 else if (type2 == STTYPE_ARITHMETIC) {
1043 ftype2 = check_arithmetic(dfw, st_arg2, ftype1);
1045 if (!compatible_ftypes(ftype1, ftype2)) {
1046 FAIL(dfw, st_arg2, "%s and %s are not of compatible types.",
1047 stnode_todisplay(st_arg1), stnode_todisplay(st_arg2));
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));
1055 else {
1056 ASSERT_STTYPE_NOT_REACHED(type2);
1060 static void
1061 check_relation_LHS_FVALUE(dfwork_t *dfw, stnode_op_t st_op,
1062 FtypeCanFunc can_func, bool allow_partial_value,
1063 stnode_t *st_node,
1064 stnode_t *st_arg1, stnode_t *st_arg2,
1065 ftenum_t logical_ftype)
1067 sttype_id_t type1, type2;
1068 header_field_info *hfinfo2 = NULL;
1069 ftenum_t ftype2;
1070 bool mk_val_string = false;
1072 LOG_NODE(st_node);
1074 type2 = stnode_type_id(st_arg2);
1076 if (IS_FIELD_ENTITY(type2)) {
1077 hfinfo2 = sttype_field_hfinfo(st_arg2);
1078 ftype2 = sttype_field_ftenum(st_arg2);
1080 if (!can_func(ftype2)) {
1081 FAIL(dfw, st_arg2, "%s (type=%s) cannot participate in specified comparison.",
1082 stnode_todisplay(st_arg2), ftype_pretty_name(ftype2));
1084 if (type2 == STTYPE_FIELD) {
1085 dfw->field_count++;
1088 else if (type2 == STTYPE_STRING ||
1089 type2 == STTYPE_LITERAL ||
1090 type2 == STTYPE_CHARCONST ||
1091 type2 == STTYPE_NUMBER ||
1092 type2 == STTYPE_PCRE) {
1093 FAIL(dfw, st_node, "Constant expression is invalid.");
1095 else if (type2 == STTYPE_SLICE) {
1096 ftype2 = check_slice(dfw, st_arg2, logical_ftype);
1098 if (!can_func(ftype2)) {
1099 FAIL(dfw, st_arg2, "%s (type=%s) cannot participate in specified comparison.",
1100 stnode_todisplay(st_arg2), ftype_pretty_name(ftype2));
1103 else if (type2 == STTYPE_FUNCTION) {
1104 ftype2 = check_function(dfw, st_arg2, logical_ftype);
1106 if (!can_func(ftype2)) {
1107 FAIL(dfw, st_arg2, "return value of %s() (type=%s) cannot participate in specified comparison.",
1108 sttype_function_name(st_arg2), ftype_pretty_name(ftype2));
1111 else if (type2 == STTYPE_ARITHMETIC) {
1112 ftype2 = check_arithmetic(dfw, st_arg2, logical_ftype);
1114 if (!can_func(ftype2)) {
1115 FAIL(dfw, st_arg2, "%s (type=%s) cannot participate in specified comparison.",
1116 stnode_todisplay(st_arg2), ftype_pretty_name(ftype2));
1119 else {
1120 ASSERT_STTYPE_NOT_REACHED(type2);
1123 type1 = stnode_type_id(st_arg1);
1124 if (type1 == STTYPE_STRING) {
1125 mk_val_string = dfilter_fvalue_from_string(dfw, ftype2, st_arg1, hfinfo2);
1127 else if (type1 == STTYPE_LITERAL) {
1128 mk_val_string = dfilter_fvalue_from_literal(dfw, ftype2, st_arg1, allow_partial_value, hfinfo2);
1130 else if (type1 == STTYPE_CHARCONST) {
1131 dfilter_fvalue_from_charconst(dfw, ftype2, st_arg1);
1133 else if (type1 == STTYPE_NUMBER) {
1134 dfilter_fvalue_from_number(dfw, ftype2, st_arg1);
1136 else {
1137 ASSERT_STTYPE_NOT_REACHED(type1);
1139 if (mk_val_string) {
1140 sttype_field_set_value_string(st_arg2, true);
1141 // Value strings can only be ordered if they are numerical.
1142 // Don't try to order them lexicographically, that's not
1143 // what users expect.
1144 if (!op_is_equality(st_op)) {
1145 FAIL(dfw, st_arg1, "Cannot use order comparisons with \"%s\" "
1146 "because the value string cannot be uniquely converted to an integer.",
1147 stnode_todisplay(st_arg1));
1152 static void
1153 check_relation_LHS_SLICE(dfwork_t *dfw, stnode_op_t st_op _U_,
1154 FtypeCanFunc can_func _U_,
1155 bool allow_partial_value,
1156 stnode_t *st_node _U_,
1157 stnode_t *st_arg1, stnode_t *st_arg2,
1158 ftenum_t logical_ftype)
1160 sttype_id_t type2;
1161 ftenum_t ftype1, ftype2;
1163 LOG_NODE(st_node);
1165 ftype1 = check_slice(dfw, st_arg1, logical_ftype);
1166 if (!can_func(ftype1)) {
1167 FAIL(dfw, st_arg1, "%s cannot participate in %s comparison.",
1168 stnode_todisplay(st_arg1), stnode_todisplay(st_node));
1171 type2 = stnode_type_id(st_arg2);
1173 if (IS_FIELD_ENTITY(type2)) {
1174 ftype2 = sttype_field_ftenum(st_arg2);
1176 if (!is_bytes_type(ftype2)) {
1177 if (!ftype_can_slice(ftype2)) {
1178 FAIL(dfw, st_arg2, "\"%s\" is a %s and cannot be converted into a sequence of bytes.",
1179 stnode_todisplay(st_arg2),
1180 ftype_pretty_name(ftype2));
1183 /* Convert entire field to bytes */
1184 convert_to_bytes(st_arg2);
1186 if (type2 == STTYPE_FIELD) {
1187 dfw->field_count++;
1190 else if (type2 == STTYPE_STRING) {
1191 dfilter_fvalue_from_string(dfw, ftype1, st_arg2, NULL);
1193 else if (type2 == STTYPE_LITERAL) {
1194 dfilter_fvalue_from_literal(dfw, ftype1, st_arg2, allow_partial_value, NULL);
1196 else if (type2 == STTYPE_CHARCONST) {
1197 dfilter_fvalue_from_charconst(dfw, ftype1, st_arg2);
1199 else if (type2 == STTYPE_NUMBER) {
1200 dfilter_fvalue_from_number(dfw, ftype1, st_arg2);
1202 else if (type2 == STTYPE_SLICE) {
1203 ftype2 = check_slice(dfw, st_arg2, ftype1);
1205 if (!compatible_ftypes(ftype1, ftype2)) {
1206 FAIL(dfw, st_arg2, "%s and %s are not of compatible types.",
1207 stnode_todisplay(st_arg1), stnode_todisplay(st_arg2));
1209 if (!can_func(ftype2)) {
1210 FAIL(dfw, st_arg2, "%s (type=%s) cannot participate in specified comparison.",
1211 stnode_todisplay(st_arg2), ftype_pretty_name(ftype2));
1214 else if (type2 == STTYPE_FUNCTION) {
1215 ftype2 = check_function(dfw, st_arg2, ftype1);
1217 if (!is_bytes_type(ftype2)) {
1218 if (!ftype_can_slice(ftype2)) {
1219 FAIL(dfw, st_arg2, "Return value of function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
1220 sttype_function_name(st_arg2),
1221 ftype_pretty_name(ftype2));
1224 /* Convert function result to bytes */
1225 convert_to_bytes(st_arg2);
1228 else if (type2 == STTYPE_PCRE) {
1229 ws_assert(st_op == STNODE_OP_MATCHES);
1231 else if (type2 == STTYPE_ARITHMETIC) {
1232 ftype2 = check_arithmetic(dfw, st_arg2, ftype1);
1234 if (!compatible_ftypes(ftype1, ftype2)) {
1235 FAIL(dfw, st_arg2, "%s and %s are not of compatible types.",
1236 stnode_todisplay(st_arg1), stnode_todisplay(st_arg2));
1239 if (!can_func(ftype2)) {
1240 FAIL(dfw, st_arg2, "%s (type=%s) cannot participate in specified comparison.",
1241 stnode_todisplay(st_arg2), ftype_pretty_name(ftype2));
1244 else {
1245 ASSERT_STTYPE_NOT_REACHED(type2);
1249 /* If the LHS of a relation test is a FUNCTION, run some checks
1250 * and possibly some modifications of syntax tree nodes. */
1251 static void
1252 check_relation_LHS_FUNCTION(dfwork_t *dfw, stnode_op_t st_op _U_,
1253 FtypeCanFunc can_func, bool allow_partial_value,
1254 stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2,
1255 ftenum_t logical_ftype)
1257 sttype_id_t type2;
1258 ftenum_t ftype1, ftype2;
1260 LOG_NODE(st_node);
1262 ftype1 = check_function(dfw, st_arg1, logical_ftype);
1263 if (!can_func(ftype1)) {
1264 FAIL(dfw, st_arg1, "Function %s (type=%s) cannot participate in %s comparison.",
1265 sttype_function_name(st_arg1), ftype_pretty_name(ftype1),
1266 stnode_todisplay(st_node));
1269 type2 = stnode_type_id(st_arg2);
1271 if (IS_FIELD_ENTITY(type2)) {
1272 ftype2 = sttype_field_ftenum(st_arg2);
1274 if (!compatible_ftypes(ftype1, ftype2)) {
1275 FAIL(dfw, st_arg2, "Function %s and %s are not of compatible types.",
1276 sttype_function_name(st_arg1), stnode_todisplay(st_arg2));
1278 /* Do this check even though you'd think that if
1279 * they're compatible, then can_func() would pass. */
1280 if (!can_func(ftype2)) {
1281 FAIL(dfw, st_arg2, "%s (type=%s) cannot participate in specified comparison.",
1282 stnode_todisplay(st_arg2), ftype_pretty_name(ftype2));
1284 if (type2 == STTYPE_FIELD) {
1285 dfw->field_count++;
1288 else if (type2 == STTYPE_STRING) {
1289 dfilter_fvalue_from_string(dfw, ftype1, st_arg2, NULL);
1291 else if (type2 == STTYPE_LITERAL) {
1292 dfilter_fvalue_from_literal(dfw, ftype1, st_arg2, allow_partial_value, NULL);
1294 else if (type2 == STTYPE_CHARCONST) {
1295 dfilter_fvalue_from_charconst(dfw, ftype1, st_arg2);
1297 else if (type2 == STTYPE_NUMBER) {
1298 dfilter_fvalue_from_number(dfw, ftype1, st_arg2);
1300 else if (type2 == STTYPE_SLICE) {
1301 ftype2 = check_slice(dfw, st_arg2, ftype1);
1303 if (!compatible_ftypes(ftype1, ftype2)) {
1304 FAIL(dfw, st_arg2, "%s and %s are not of compatible types.",
1305 stnode_todisplay(st_arg1), stnode_todisplay(st_arg2));
1307 if (!can_func(ftype2)) {
1308 FAIL(dfw, st_arg2, "%s (type=%s) cannot participate in specified comparison.",
1309 stnode_todisplay(st_arg2), ftype_pretty_name(ftype2));
1312 if (!is_bytes_type(ftype1)) {
1313 if (!ftype_can_slice(ftype1)) {
1314 FAIL(dfw, st_arg1, "Function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
1315 sttype_function_name(st_arg1),
1316 ftype_pretty_name(ftype1));
1319 /* Convert function result to bytes */
1320 convert_to_bytes(st_arg1);
1323 else if (type2 == STTYPE_FUNCTION) {
1324 ftype2 = check_function(dfw, st_arg2, ftype1);
1326 if (!compatible_ftypes(ftype1, ftype2)) {
1327 FAIL(dfw, st_arg2, "Return values of function %s (type=%s) and function %s (type=%s) are not of compatible types.",
1328 sttype_function_name(st_arg1), ftype_pretty_name(ftype1), sttype_function_name(st_arg1), ftype_pretty_name(ftype2));
1331 /* Do this check even though you'd think that if
1332 * they're compatible, then can_func() would pass. */
1333 if (!can_func(ftype2)) {
1334 FAIL(dfw, st_arg2, "Return value of %s (type=%s) cannot participate in specified comparison.",
1335 sttype_function_name(st_arg2), ftype_pretty_name(ftype2));
1338 else if (type2 == STTYPE_PCRE) {
1339 ws_assert(st_op == STNODE_OP_MATCHES);
1341 else if (type2 == STTYPE_ARITHMETIC) {
1342 ftype2 = check_arithmetic(dfw, st_arg2, ftype1);
1344 if (!compatible_ftypes(ftype1, ftype2)) {
1345 FAIL(dfw, st_arg2, "%s and %s are not of compatible types.",
1346 stnode_todisplay(st_arg1), stnode_todisplay(st_arg2));
1349 if (!can_func(ftype2)) {
1350 FAIL(dfw, st_arg2, "%s (type=%s) cannot participate in specified comparison.",
1351 stnode_todisplay(st_arg2), ftype_pretty_name(ftype2));
1354 else {
1355 ASSERT_STTYPE_NOT_REACHED(type2);
1359 static void
1360 check_relation_LHS_ARITHMETIC(dfwork_t *dfw, stnode_op_t st_op _U_,
1361 FtypeCanFunc can_func, bool allow_partial_value,
1362 stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2,
1363 ftenum_t logical_ftype)
1365 sttype_id_t type2;
1366 ftenum_t ftype1, ftype2;
1368 LOG_NODE(st_node);
1370 ftype1 = check_arithmetic(dfw, st_arg1, logical_ftype);
1371 if (!can_func(ftype1)) {
1372 FAIL(dfw, st_arg1, "Result with type %s cannot participate in %s comparison.",
1373 ftype_pretty_name(ftype1),
1374 stnode_todisplay(st_node));
1377 type2 = stnode_type_id(st_arg2);
1379 if (IS_FIELD_ENTITY(type2)) {
1380 ftype2 = sttype_field_ftenum(st_arg2);
1382 if (!compatible_ftypes(ftype1, ftype2)) {
1383 FAIL(dfw, st_arg2, "%s and %s are not of compatible types.",
1384 stnode_todisplay(st_arg1), stnode_todisplay(st_arg2));
1386 if (!can_func(ftype2)) {
1387 FAIL(dfw, st_arg2, "%s (type=%s) cannot participate in specified comparison.",
1388 stnode_todisplay(st_arg2), ftype_pretty_name(ftype2));
1390 if (type2 == STTYPE_FIELD) {
1391 dfw->field_count++;
1394 else if (type2 == STTYPE_STRING) {
1395 dfilter_fvalue_from_string(dfw, ftype1, st_arg2, NULL);
1397 else if (type2 == STTYPE_LITERAL) {
1398 dfilter_fvalue_from_literal(dfw, ftype1, st_arg2, allow_partial_value, NULL);
1400 else if (type2 == STTYPE_CHARCONST) {
1401 dfilter_fvalue_from_charconst(dfw, ftype1, st_arg2);
1403 else if (type2 == STTYPE_NUMBER) {
1404 dfilter_fvalue_from_number(dfw, ftype1, st_arg2);
1406 else if (type2 == STTYPE_SLICE) {
1407 ftype2 = check_slice(dfw, st_arg2, ftype1);
1409 if (!compatible_ftypes(ftype1, ftype2)) {
1410 FAIL(dfw, st_arg2, "%s and %s are not of compatible types.",
1411 stnode_todisplay(st_arg1), stnode_todisplay(st_arg2));
1413 if (!can_func(ftype2)) {
1414 FAIL(dfw, st_arg2, "%s (type=%s) cannot participate in specified comparison.",
1415 stnode_todisplay(st_arg2), ftype_pretty_name(ftype2));
1418 if (!is_bytes_type(ftype1)) {
1419 if (!ftype_can_slice(ftype1)) {
1420 FAIL(dfw, st_arg1, "Result is a %s and cannot be converted into a sequence of bytes.",
1421 ftype_pretty_name(ftype1));
1424 /* Convert expression result to bytes */
1425 convert_to_bytes(st_arg1);
1428 else if (type2 == STTYPE_FUNCTION) {
1429 ftype2 = check_function(dfw, st_arg2, ftype1);
1431 if (!compatible_ftypes(ftype1, ftype2)) {
1432 FAIL(dfw, st_arg2, "Result (type=%s) and return value of %s() (type=%s) are not of compatible types.",
1433 ftype_pretty_name(ftype1),
1434 sttype_function_name(st_arg2), ftype_pretty_name(ftype2));
1436 if (!can_func(ftype2)) {
1437 FAIL(dfw, st_arg2, "return value of %s() (type=%s) cannot participate in specified comparison.",
1438 sttype_function_name(st_arg2), ftype_pretty_name(ftype2));
1441 else if (type2 == STTYPE_PCRE) {
1442 ws_assert(st_op == STNODE_OP_MATCHES);
1444 else if (type2 == STTYPE_ARITHMETIC) {
1445 ftype2 = check_arithmetic(dfw, st_arg2, ftype1);
1447 if (!compatible_ftypes(ftype1, ftype2)) {
1448 FAIL(dfw, st_arg2, "%s and %s are not of compatible types.",
1449 stnode_todisplay(st_arg1), stnode_todisplay(st_arg2));
1451 if (!can_func(ftype2)) {
1452 FAIL(dfw, st_arg2, "%s (type=%s) cannot participate in specified comparison.",
1453 stnode_todisplay(st_arg2), ftype_pretty_name(ftype2));
1456 else {
1457 ASSERT_STTYPE_NOT_REACHED(type2);
1461 /* Check the semantics of any relational test. */
1462 static void
1463 check_relation(dfwork_t *dfw, stnode_op_t st_op,
1464 FtypeCanFunc can_func, bool allow_partial_value,
1465 stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
1467 resolve_unparsed(dfw, st_arg1, true);
1468 resolve_unparsed(dfw, st_arg2, false);
1470 LOG_NODE(st_node);
1472 switch (stnode_type_id(st_arg1)) {
1473 case STTYPE_FIELD:
1474 case STTYPE_REFERENCE:
1475 case STTYPE_UNPARSED:
1476 check_relation_LHS_FIELD(dfw, st_op, can_func,
1477 allow_partial_value, st_node, st_arg1, st_arg2);
1478 break;
1479 case STTYPE_SLICE:
1480 check_relation_LHS_SLICE(dfw, st_op, can_func,
1481 allow_partial_value, st_node, st_arg1, st_arg2, find_logical_ftype(dfw, st_node));
1482 break;
1483 case STTYPE_FUNCTION:
1484 check_relation_LHS_FUNCTION(dfw, st_op, can_func,
1485 allow_partial_value, st_node, st_arg1, st_arg2, find_logical_ftype(dfw, st_node));
1486 break;
1487 case STTYPE_ARITHMETIC:
1488 check_relation_LHS_ARITHMETIC(dfw, st_op, can_func,
1489 allow_partial_value, st_node, st_arg1, st_arg2, find_logical_ftype(dfw, st_node));
1490 break;
1491 case STTYPE_LITERAL:
1492 case STTYPE_STRING:
1493 case STTYPE_CHARCONST:
1494 case STTYPE_NUMBER:
1495 check_relation_LHS_FVALUE(dfw, st_op, can_func,
1496 allow_partial_value, st_node, st_arg1, st_arg2, find_logical_ftype(dfw, st_node));
1497 break;
1498 case STTYPE_UNINITIALIZED:
1499 case STTYPE_PCRE:
1500 case STTYPE_FVALUE:
1501 case STTYPE_TEST:
1502 case STTYPE_SET:
1503 case STTYPE_NUM_TYPES:
1504 ASSERT_STTYPE_NOT_REACHED(stnode_type_id(st_arg1));
1508 static void
1509 check_warning_contains_RHS_FIELD(dfwork_t *dfw, stnode_t *st_node _U_,
1510 stnode_t *st_arg1 _U_, stnode_t *st_arg2)
1512 const char *token = stnode_token(st_arg2);
1513 header_field_info *hfinfo = sttype_field_hfinfo(st_arg2);
1514 fvalue_t *fvalue = fvalue_from_literal(FT_BYTES, token, true, NULL);
1515 if (fvalue != NULL) {
1516 char *repr = fvalue_to_string_repr(dfw->dfw_scope, fvalue, FTREPR_DFILTER, 0);
1517 add_compile_warning(dfw, "Interpreting \"%s\" as %s instead of %s. "
1518 "Consider writing \"%s\" or \".%s\" to remove this warning",
1519 token, hfinfo->name, ftype_pretty_name(FT_BYTES),
1520 repr, hfinfo->abbrev);
1521 fvalue_free(fvalue);
1525 static void
1526 check_relation_contains(dfwork_t *dfw, stnode_t *st_node,
1527 stnode_t *st_arg1, stnode_t *st_arg2)
1529 resolve_unparsed(dfw, st_arg1, true);
1530 resolve_unparsed(dfw, st_arg2, false);
1532 LOG_NODE(st_node);
1534 if (stnode_type_id(st_arg2) == STTYPE_FIELD && stnode_get_flags(st_arg2, STFLAG_UNPARSED)) {
1535 check_warning_contains_RHS_FIELD(dfw, st_node, st_arg1, st_arg2);
1538 switch (stnode_type_id(st_arg1)) {
1539 case STTYPE_FIELD:
1540 case STTYPE_REFERENCE:
1541 case STTYPE_UNPARSED:
1542 check_relation_LHS_FIELD(dfw, STNODE_OP_CONTAINS, ftype_can_contains,
1543 true, st_node, st_arg1, st_arg2);
1544 break;
1545 case STTYPE_FUNCTION:
1546 check_relation_LHS_FUNCTION(dfw, STNODE_OP_CONTAINS, ftype_can_contains,
1547 true, st_node, st_arg1, st_arg2, find_logical_ftype(dfw, st_node));
1548 break;
1549 case STTYPE_SLICE:
1550 check_relation_LHS_SLICE(dfw, STNODE_OP_CONTAINS, ftype_can_contains,
1551 true, st_node, st_arg1, st_arg2, find_logical_ftype(dfw, st_node));
1552 break;
1553 default:
1554 FAIL(dfw, st_arg1, "Left side of %s expression must be a field or function, not %s.",
1555 stnode_todisplay(st_node), stnode_todisplay(st_arg1));
1560 static void
1561 check_relation_matches(dfwork_t *dfw, stnode_t *st_node,
1562 stnode_t *st_arg1, stnode_t *st_arg2)
1564 ws_regex_t *pcre;
1565 char *errmsg = NULL;
1566 GString *patt;
1568 resolve_unparsed(dfw, st_arg1, true);
1570 LOG_NODE(st_node);
1572 if (stnode_type_id(st_arg2) != STTYPE_STRING) {
1573 FAIL(dfw, st_arg2, "Matches requires a double quoted string on the right side.");
1576 patt = stnode_string(st_arg2);
1577 ws_debug("Compile regex pattern: %s", stnode_token(st_arg2));
1579 pcre = ws_regex_compile_ex(patt->str, patt->len, &errmsg, WS_REGEX_CASELESS|WS_REGEX_NEVER_UTF);
1580 if (errmsg) {
1581 dfilter_fail(dfw, DF_ERROR_GENERIC, stnode_location(st_arg2), "Regex compilation error: %s.", errmsg);
1582 g_free(errmsg);
1583 ws_noisy("Semantic check failed here with a regex syntax error");
1584 THROW(TypeError);
1587 stnode_replace(st_arg2, STTYPE_PCRE, pcre);
1589 switch (stnode_type_id(st_arg1)) {
1590 case STTYPE_FIELD:
1591 case STTYPE_REFERENCE:
1592 check_relation_LHS_FIELD(dfw, STNODE_OP_MATCHES, ftype_can_matches,
1593 true, st_node, st_arg1, st_arg2);
1594 break;
1595 case STTYPE_FUNCTION:
1596 check_relation_LHS_FUNCTION(dfw, STNODE_OP_MATCHES, ftype_can_matches,
1597 true, st_node, st_arg1, st_arg2, find_logical_ftype(dfw, st_arg1));
1598 break;
1599 case STTYPE_SLICE:
1600 check_relation_LHS_SLICE(dfw, STNODE_OP_MATCHES, ftype_can_matches,
1601 true, st_node, st_arg1, st_arg2, find_logical_ftype(dfw, st_arg1));
1602 break;
1603 default:
1604 FAIL(dfw, st_arg1, "Left side of %s expression must be a field or function, not %s.",
1605 stnode_todisplay(st_node), stnode_todisplay(st_arg1));
1609 static void
1610 check_relation_in(dfwork_t *dfw, stnode_t *st_node _U_,
1611 stnode_t *st_arg1, stnode_t *st_arg2)
1613 GSList *nodelist;
1614 stnode_t *node_left, *node_right;
1616 resolve_unparsed(dfw, st_arg1, true);
1617 resolve_unparsed(dfw, st_arg2, false);
1619 LOG_NODE(st_node);
1621 if (stnode_type_id(st_arg1) != STTYPE_FIELD) {
1622 FAIL(dfw, st_arg1, "Only a field may be tested for membership in a set.");
1624 /* Checked in the grammar parser. */
1625 ws_assert(stnode_type_id(st_arg2) == STTYPE_SET);
1627 /* Attempt to interpret one element of the set at a time. Each
1628 * element is represented by two items in the list, the element
1629 * value and NULL. Both will be replaced by a lower and upper
1630 * value if the element is a range. */
1631 nodelist = stnode_data(st_arg2);
1632 while (nodelist) {
1633 node_left = nodelist->data;
1634 resolve_unparsed(dfw, node_left, false);
1636 /* Don't let a range on the RHS affect the LHS field. */
1637 if (stnode_type_id(node_left) == STTYPE_SLICE) {
1638 FAIL(dfw, node_left, "A slice may not appear inside a set.");
1639 break;
1642 nodelist = g_slist_next(nodelist);
1643 ws_assert(nodelist);
1644 node_right = nodelist->data;
1645 if (node_right) {
1646 resolve_unparsed(dfw, node_right, false);
1647 check_relation_LHS_FIELD(dfw, STNODE_OP_GE, ftype_can_cmp,
1648 false, st_node, st_arg1, node_left);
1649 check_relation_LHS_FIELD(dfw, STNODE_OP_LE, ftype_can_cmp,
1650 false, st_node, st_arg1, node_right);
1651 } else {
1652 check_relation_LHS_FIELD(dfw, STNODE_OP_ANY_EQ, ftype_can_eq,
1653 false, st_node, st_arg1, node_left);
1655 nodelist = g_slist_next(nodelist);
1659 /* Check the semantics of any type of TEST */
1660 static void
1661 check_test(dfwork_t *dfw, stnode_t *st_node)
1663 stnode_op_t st_op;
1664 stnode_t *st_arg1, *st_arg2;
1666 LOG_NODE(st_node);
1668 sttype_oper_get(st_node, &st_op, &st_arg1, &st_arg2);
1670 switch (st_op) {
1671 case STNODE_OP_NOT:
1672 semcheck(dfw, st_arg1);
1673 break;
1674 case STNODE_OP_AND:
1675 case STNODE_OP_OR:
1676 semcheck(dfw, st_arg1);
1677 semcheck(dfw, st_arg2);
1678 break;
1679 case STNODE_OP_ALL_EQ:
1680 case STNODE_OP_ANY_EQ:
1681 case STNODE_OP_ALL_NE:
1682 case STNODE_OP_ANY_NE:
1683 check_relation(dfw, st_op, ftype_can_eq, false, st_node, st_arg1, st_arg2);
1684 break;
1685 case STNODE_OP_GT:
1686 case STNODE_OP_GE:
1687 case STNODE_OP_LT:
1688 case STNODE_OP_LE:
1689 check_relation(dfw, st_op, ftype_can_cmp, false, st_node, st_arg1, st_arg2);
1690 break;
1691 case STNODE_OP_CONTAINS:
1692 check_relation_contains(dfw, st_node, st_arg1, st_arg2);
1693 break;
1694 case STNODE_OP_MATCHES:
1695 check_relation_matches(dfw, st_node, st_arg1, st_arg2);
1696 break;
1697 case STNODE_OP_IN:
1698 case STNODE_OP_NOT_IN:
1699 check_relation_in(dfw, st_node, st_arg1, st_arg2);
1700 break;
1702 case STNODE_OP_UNINITIALIZED:
1703 case STNODE_OP_UNARY_MINUS:
1704 case STNODE_OP_BITWISE_AND:
1705 case STNODE_OP_ADD:
1706 case STNODE_OP_SUBTRACT:
1707 case STNODE_OP_MULTIPLY:
1708 case STNODE_OP_DIVIDE:
1709 case STNODE_OP_MODULO:
1710 ASSERT_STNODE_OP_NOT_REACHED(st_op);
1714 static ftenum_t
1715 check_nonzero(dfwork_t *dfw, stnode_t *st_node)
1717 ftenum_t ftype;
1719 LOG_NODE(st_node);
1721 switch (stnode_type_id(st_node)) {
1722 case STTYPE_ARITHMETIC:
1723 ftype = check_arithmetic(dfw, st_node, find_logical_ftype(dfw, st_node));
1724 break;
1725 case STTYPE_SLICE:
1726 ftype = check_slice(dfw, st_node, find_logical_ftype(dfw, st_node));
1727 break;
1728 case STTYPE_FUNCTION:
1729 ftype = check_function(dfw, st_node, find_logical_ftype(dfw, st_node));
1730 break;
1731 default:
1732 ASSERT_STTYPE_NOT_REACHED(stnode_type_id(st_node));
1735 if (!ftype_can_is_zero(ftype)) {
1736 FAIL(dfw, st_node, "Type %s cannot be assigned a truth value.",
1737 ftype_pretty_name(ftype));
1740 return ftype;
1743 static const char *
1744 op_to_error_msg(stnode_op_t st_op)
1746 switch (st_op) {
1747 case STNODE_OP_UNARY_MINUS:
1748 return "cannot be negated";
1749 case STNODE_OP_ADD:
1750 return "cannot be added";
1751 case STNODE_OP_SUBTRACT:
1752 return "cannot be subtracted";
1753 case STNODE_OP_MULTIPLY:
1754 return "cannot be multiplied";
1755 case STNODE_OP_DIVIDE:
1756 return "cannot be divided";
1757 case STNODE_OP_MODULO:
1758 return "does not support modulo operation";
1759 case STNODE_OP_BITWISE_AND:
1760 return "does not support bitwise AND";
1761 default:
1762 return "cannot FIXME";
1766 static void
1767 do_unary_minus(dfwork_t *dfw, stnode_t *st_node, stnode_t *st_arg1)
1769 char *err_msg;
1770 fvalue_t *new_fv = fvalue_unary_minus(stnode_data(st_arg1), &err_msg);
1771 if (new_fv == NULL)
1772 FAIL_MSG(dfw, st_node, err_msg);
1773 stnode_replace(st_node, STTYPE_FVALUE, new_fv);
1776 static void
1777 do_addition(dfwork_t *dfw, stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
1779 char *err_msg;
1780 fvalue_t *new_fv = fvalue_add(stnode_data(st_arg1), stnode_data(st_arg2), &err_msg);
1781 if (new_fv == NULL)
1782 FAIL_MSG(dfw, st_node, err_msg);
1783 stnode_replace(st_node, STTYPE_FVALUE, new_fv);
1786 static void
1787 do_subtraction(dfwork_t *dfw, stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
1789 char *err_msg;
1790 fvalue_t *new_fv = fvalue_subtract(stnode_data(st_arg1), stnode_data(st_arg2), &err_msg);
1791 if (new_fv == NULL)
1792 FAIL_MSG(dfw, st_node, err_msg);
1793 stnode_replace(st_node, STTYPE_FVALUE, new_fv);
1796 static void
1797 do_multiplication(dfwork_t *dfw, stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
1799 char *err_msg;
1800 fvalue_t *new_fv = fvalue_multiply(stnode_data(st_arg1), stnode_data(st_arg2), &err_msg);
1801 if (new_fv == NULL)
1802 FAIL_MSG(dfw, st_node, err_msg);
1803 stnode_replace(st_node, STTYPE_FVALUE, new_fv);
1806 static void
1807 do_division(dfwork_t *dfw, stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
1809 if (fvalue_is_zero(stnode_data(st_arg2)))
1810 FAIL(dfw, st_node, "Division by zero");
1812 char *err_msg;
1813 fvalue_t *new_fv = fvalue_divide(stnode_data(st_arg1), stnode_data(st_arg2), &err_msg);
1814 if (new_fv == NULL)
1815 FAIL_MSG(dfw, st_node, err_msg);
1816 stnode_replace(st_node, STTYPE_FVALUE, new_fv);
1819 static void
1820 do_modulo(dfwork_t *dfw, stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
1822 if (fvalue_is_zero(stnode_data(st_arg2)))
1823 FAIL(dfw, st_node, "Division by zero");
1825 char *err_msg;
1826 fvalue_t *new_fv = fvalue_modulo(stnode_data(st_arg1), stnode_data(st_arg2), &err_msg);
1827 if (new_fv == NULL)
1828 FAIL_MSG(dfw, st_node, err_msg);
1829 stnode_replace(st_node, STTYPE_FVALUE, new_fv);
1832 static void
1833 do_bitwise_and(dfwork_t *dfw, stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
1835 char *err_msg;
1836 fvalue_t *new_fv = fvalue_bitwise_and(stnode_data(st_arg1), stnode_data(st_arg2), &err_msg);
1837 if (new_fv == NULL)
1838 FAIL_MSG(dfw, st_node, err_msg);
1839 stnode_replace(st_node, STTYPE_FVALUE, new_fv);
1842 static ftenum_t
1843 check_arithmetic_LHS_NUMBER(dfwork_t *dfw, stnode_op_t st_op,
1844 stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2,
1845 ftenum_t logical_ftype)
1847 ftenum_t ftype1, ftype2;
1848 FtypeCanFunc can_func = NULL;
1849 ArithmeticDoFunc do_func = NULL;
1851 LOG_NODE(st_node);
1853 if (st_op == STNODE_OP_UNARY_MINUS) {
1854 ftype1 = check_arithmetic(dfw, st_arg1, logical_ftype);
1855 if (!ftype_can_unary_minus(ftype1)) {
1856 FAIL(dfw, st_arg1, "%s %s.",
1857 ftype_name(ftype1), op_to_error_msg(st_op));
1859 if (dfw->flags & DF_OPTIMIZE && stnode_type_id(st_arg1) == STTYPE_FVALUE) {
1860 /* Pre-compute constant result */
1861 do_unary_minus(dfw, st_node, st_arg1);
1863 return ftype1;
1866 switch (st_op) {
1867 case STNODE_OP_ADD:
1868 can_func = ftype_can_add;
1869 do_func = do_addition;
1870 break;
1871 case STNODE_OP_SUBTRACT:
1872 can_func = ftype_can_subtract;
1873 do_func = do_subtraction;
1874 break;
1875 case STNODE_OP_MULTIPLY:
1876 can_func = ftype_can_multiply;
1877 do_func = do_multiplication;
1878 break;
1879 case STNODE_OP_DIVIDE:
1880 can_func = ftype_can_divide;
1881 do_func = do_division;
1882 break;
1883 case STNODE_OP_MODULO:
1884 can_func = ftype_can_modulo;
1885 do_func = do_modulo;
1886 break;
1887 case STNODE_OP_BITWISE_AND:
1888 can_func = ftype_can_bitwise_and;
1889 do_func = do_bitwise_and;
1890 break;
1891 default:
1892 ASSERT_STNODE_OP_NOT_REACHED(st_op);
1895 ftype1 = check_arithmetic(dfw, st_arg1, logical_ftype);
1896 if (!can_func(ftype1)) {
1897 FAIL(dfw, st_arg1, "%s %s.",
1898 ftype_name(ftype1), op_to_error_msg(st_op));
1901 ftype2 = check_arithmetic(dfw, st_arg2, ftype1);
1902 if (!can_func(ftype2)) {
1903 FAIL(dfw, st_arg2, "%s %s.",
1904 ftype_name(ftype2), op_to_error_msg(st_op));
1907 if (!compatible_ftypes(ftype1, ftype2)) {
1908 FAIL(dfw, st_node, "%s and %s are not compatible.",
1909 ftype_name(ftype1), ftype_name(ftype2));
1912 if (dfw->flags & DF_OPTIMIZE &&
1913 stnode_type_id(st_arg1) == STTYPE_FVALUE &&
1914 stnode_type_id(st_arg2) == STTYPE_FVALUE) {
1915 /* Pre-compute constant result */
1916 do_func(dfw, st_node, st_arg1, st_arg2);
1919 return ftype1;
1923 * Time arithmetic with scalar multiplication/division only.
1924 * An extra limitation is that multiplicative scalars must appear on the
1925 * RHS currently.
1927 static ftenum_t
1928 check_arithmetic_LHS_TIME(dfwork_t *dfw, stnode_op_t st_op, stnode_t *st_node,
1929 stnode_t *st_arg1, stnode_t *st_arg2,
1930 ftenum_t logical_ftype)
1932 ftenum_t ftype1, ftype2;
1933 ArithmeticDoFunc do_func = NULL;
1935 sttype_oper_get(st_node, &st_op, &st_arg1, &st_arg2);
1937 LOG_NODE(st_node);
1939 if (st_op == STNODE_OP_UNARY_MINUS) {
1940 ftype1 = check_arithmetic(dfw, st_arg1, logical_ftype);
1941 if (dfw->flags & DF_OPTIMIZE && stnode_type_id(st_arg1) == STTYPE_FVALUE) {
1942 do_unary_minus(dfw, st_node, st_arg1);
1944 return ftype1;
1947 switch (st_op) {
1948 case STNODE_OP_ADD:
1949 case STNODE_OP_SUBTRACT:
1950 ftype1 = check_arithmetic(dfw, st_arg1, logical_ftype);
1951 if (!FT_IS_TIME(ftype1)) {
1952 FAIL(dfw, st_node, "Left hand side must be a time type, not %s.", ftype_pretty_name(ftype1));
1954 ftype2 = check_arithmetic(dfw, st_arg2, logical_ftype);
1955 if (!FT_IS_TIME(ftype2)) {
1956 FAIL(dfw, st_node, "Right hand side must be a time type, not %s.", ftype_pretty_name(ftype2));
1958 break;
1959 case STNODE_OP_MULTIPLY:
1960 case STNODE_OP_DIVIDE:
1961 ftype1 = check_arithmetic(dfw, st_arg1, logical_ftype);
1962 if (!FT_IS_TIME(ftype1)) {
1963 FAIL(dfw, st_node, "Left hand side must be a time type, not %s.", ftype_pretty_name(ftype1));
1965 ftype2 = check_arithmetic(dfw, st_arg2, FT_SCALAR);
1966 if (!FT_IS_SCALAR(ftype2)) {
1967 FAIL(dfw, st_node, "Right hand side must be an integer or float type, not %s.", ftype_pretty_name(ftype2));
1969 break;
1970 default:
1971 FAIL(dfw, st_node, "\"%s\" is not a valid arithmetic operator for %s",
1972 stnode_todisplay(st_node), ftype_pretty_name(logical_ftype));
1975 if (dfw->flags & DF_OPTIMIZE &&
1976 stnode_type_id(st_arg1) == STTYPE_FVALUE &&
1977 stnode_type_id(st_arg2) == STTYPE_FVALUE) {
1978 /* Pre-compute constant result */
1979 switch (st_op) {
1980 case STNODE_OP_ADD:
1981 do_func = do_addition;
1982 break;
1983 case STNODE_OP_SUBTRACT:
1984 do_func = do_subtraction;
1985 break;
1986 case STNODE_OP_MULTIPLY:
1987 do_func = do_multiplication;
1988 break;
1989 case STNODE_OP_DIVIDE:
1990 do_func = do_division;
1991 break;
1992 default:
1993 ASSERT_STNODE_OP_NOT_REACHED(st_op);
1995 do_func(dfw, st_node, st_arg1, st_arg2);
1998 return ftype1;
2001 ftenum_t
2002 check_arithmetic(dfwork_t *dfw, stnode_t *st_node, ftenum_t logical_ftype)
2004 sttype_id_t type;
2005 stnode_op_t st_op;
2006 stnode_t *st_arg1, *st_arg2;
2007 ftenum_t ftype = FT_NONE;
2009 LOG_NODE(st_node);
2011 resolve_unparsed(dfw, st_node, true);
2013 type = stnode_type_id(st_node);
2015 switch (type) {
2016 case STTYPE_LITERAL:
2017 dfilter_fvalue_from_literal(dfw, logical_ftype, st_node, false, NULL);
2018 ftype = sttype_pointer_ftenum(st_node);
2019 break;
2021 case STTYPE_STRING:
2022 dfilter_fvalue_from_string(dfw, logical_ftype, st_node, NULL);
2023 ftype = sttype_pointer_ftenum(st_node);
2024 break;
2026 case STTYPE_CHARCONST:
2027 dfilter_fvalue_from_charconst(dfw, logical_ftype, st_node);
2028 ftype = sttype_pointer_ftenum(st_node);
2029 break;
2031 case STTYPE_NUMBER:
2032 dfilter_fvalue_from_number(dfw, logical_ftype, st_node);
2033 ftype = sttype_pointer_ftenum(st_node);
2034 break;
2036 case STTYPE_FIELD:
2037 dfw->field_count++;
2038 /* fall-through */
2039 case STTYPE_REFERENCE:
2040 ftype = sttype_field_ftenum(st_node);
2041 break;
2043 case STTYPE_FUNCTION:
2044 ftype = check_function(dfw, st_node, logical_ftype);
2045 break;
2047 case STTYPE_SLICE:
2048 ftype = check_slice(dfw, st_node, logical_ftype);
2049 break;
2051 case STTYPE_FVALUE:
2052 ftype = sttype_pointer_ftenum(st_node);
2053 break;
2055 case STTYPE_ARITHMETIC:
2056 sttype_oper_get(st_node, &st_op, &st_arg1, &st_arg2);
2057 if (FT_IS_TIME(logical_ftype))
2058 ftype = check_arithmetic_LHS_TIME(dfw, st_op, st_node, st_arg1, st_arg2, logical_ftype);
2059 else
2060 ftype = check_arithmetic_LHS_NUMBER(dfw, st_op, st_node, st_arg1, st_arg2, logical_ftype);
2061 break;
2063 case STTYPE_SET:
2064 case STTYPE_PCRE:
2065 case STTYPE_UNPARSED:
2066 case STTYPE_UNINITIALIZED:
2067 case STTYPE_NUM_TYPES:
2068 case STTYPE_TEST:
2069 ASSERT_STTYPE_NOT_REACHED(type);
2072 return ftype;
2076 /* Check the entire syntax tree. */
2077 static ftenum_t
2078 semcheck(dfwork_t *dfw, stnode_t *st_node)
2080 /* Does FT_NONE make sense for tests and exists? We don't actually
2081 * return an fvalue in those cases, so, e.g., custom columns have
2082 * check marks, not boolean true/false.
2084 ftenum_t ftype = FT_NONE;
2086 LOG_NODE(st_node);
2088 dfw->field_count = 0;
2090 switch (stnode_type_id(st_node)) {
2091 case STTYPE_TEST:
2092 check_test(dfw, st_node);
2093 break;
2094 case STTYPE_ARITHMETIC:
2095 case STTYPE_SLICE:
2096 case STTYPE_FUNCTION:
2097 ftype = check_nonzero(dfw, st_node);
2098 break;
2099 default:
2100 ftype = check_exists(dfw, st_node);
2103 if (dfw->field_count == 0) {
2104 FAIL(dfw, st_node, "Constant expression is invalid.");
2107 return ftype;
2111 /* Check the syntax tree for semantic errors, and convert
2112 * some of the nodes into the form they need to be in order to
2113 * later generate the DFVM bytecode. */
2114 bool
2115 dfw_semcheck(dfwork_t *dfw)
2117 volatile bool ok_filter = true;
2118 volatile ftenum_t ftype = FT_NONE;
2120 ws_debug("Starting semantic check (dfw = %p)", dfw);
2122 /* Instead of having to check for errors at every stage of
2123 * the semantic-checking, the semantic-checking code will
2124 * throw an exception if a problem is found. */
2125 TRY {
2126 ftype = semcheck(dfw, dfw->st_root);
2128 CATCH(TypeError) {
2129 ok_filter = false;
2131 ENDTRY;
2133 ws_debug("Semantic check (dfw = %p) returns %s, return type %s",
2134 dfw, ok_filter ? "TRUE" : "FALSE", ftype_name(ftype));
2135 dfw->ret_type = ftype;
2137 return ok_filter;
2141 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2143 * Local variables:
2144 * c-basic-offset: 8
2145 * tab-width: 8
2146 * indent-tabs-mode: t
2147 * End:
2149 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2150 * :indentSize=8:tabSize=8:noTabs=false: