Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dfilter / semcheck.c
blob60983ff31e8e36c47ec8214cc04eddf67fcac32d
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_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,
78 MK_OK_BOOLEAN,
79 MK_OK_NUMBER,
80 MK_OK_STRING,
83 static enum mk_result
84 mk_fvalue_from_val_string(dfwork_t *dfw, header_field_info *hfinfo, const char *s, stnode_t *st);
86 static inline bool
87 op_is_equality(stnode_op_t op)
89 switch (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:
94 case STNODE_OP_IN:
95 case STNODE_OP_NOT_IN:
96 return true;
97 default:
98 return false;
102 /* Compares to ftenum_t's and decides if they're
103 * compatible or not (if they're the same basic type) */
104 bool
105 compatible_ftypes(ftenum_t a, ftenum_t b)
107 switch (a) {
108 case FT_NONE:
109 case FT_BOOLEAN:
110 case FT_PROTOCOL:
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 */
115 case FT_IPv4:
116 case FT_IPv6:
117 case FT_GUID:
118 return a == b;
120 case FT_FLOAT: /* XXX - should be able to compare with INT */
121 case FT_DOUBLE: /* XXX - should be able to compare with INT */
122 switch (b) {
123 case FT_FLOAT:
124 case FT_DOUBLE:
125 return true;
126 default:
127 return false;
130 case FT_ETHER:
131 case FT_BYTES:
132 case FT_UINT_BYTES:
133 case FT_OID:
134 case FT_VINES:
135 case FT_FCWWN:
136 case FT_REL_OID:
137 case FT_SYSTEM_ID:
138 case FT_EUI64:
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);
142 case FT_UINT8:
143 case FT_UINT16:
144 case FT_UINT24:
145 case FT_UINT32:
146 case FT_CHAR:
147 case FT_FRAMENUM:
148 case FT_IPXNET:
149 return ftype_can_val_to_uinteger(b);
151 case FT_UINT40:
152 case FT_UINT48:
153 case FT_UINT56:
154 case FT_UINT64:
155 return ftype_can_val_to_uinteger64(b);
157 case FT_INT8:
158 case FT_INT16:
159 case FT_INT24:
160 case FT_INT32:
161 return ftype_can_val_to_sinteger(b);
163 case FT_INT40:
164 case FT_INT48:
165 case FT_INT56:
166 case FT_INT64:
167 return ftype_can_val_to_sinteger64(b);
169 case FT_STRING:
170 case FT_STRINGZ:
171 case FT_UINT_STRING:
172 case FT_STRINGZPAD:
173 case FT_STRINGZTRUNC:
174 case FT_AX25:
175 return FT_IS_STRING(b);
177 case FT_NUM_TYPES:
178 case FT_SCALAR:
179 ASSERT_FTYPE_NOT_REACHED(a);
182 ws_assert_not_reached();
183 return false;
186 void
187 resolve_unparsed(dfwork_t *dfw, stnode_t *st, bool strict)
189 if (stnode_type_id(st) != STTYPE_UNPARSED)
190 return;
192 header_field_info *hfinfo = dfilter_resolve_unparsed(stnode_data(st), dfw->deprecated);
193 if (hfinfo != NULL)
194 stnode_replace(st, STTYPE_FIELD, hfinfo);
195 else if (strict)
196 FAIL(dfw, st, "\"%s\" is not a valid protocol or protocol field.", stnode_todisplay(st));
197 else
198 stnode_mutate(st, STTYPE_LITERAL);
201 /* Don't set the error message if it's already set. */
202 #define SET_ERROR(dfw, str) \
203 do { \
204 if ((str) != NULL && (dfw)->error == NULL) { \
205 (dfw)->error = df_error_new(DF_ERROR_GENERIC, str, NULL); \
207 else { \
208 g_free(str); \
210 } while (0)
212 /* Transforms a syntax node into a value and sets the error message on failure. */
213 bool
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)
217 fvalue_t *fv;
218 const char *s = stnode_data(st);
219 char *error_message = NULL;
220 enum mk_result res;
222 fv = fvalue_from_literal(ftype, s, allow_partial_value, &error_message);
223 if (fv != NULL) {
224 g_free(error_message); // error_message is expected to be null
225 stnode_replace(st, STTYPE_FVALUE, fv);
226 return false;
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;
247 // Failure
248 dfw_set_error_location(dfw, stnode_location(st));
249 FAIL_HERE(dfw);
250 ws_assert_not_reached();
253 /* Transforms a syntax node into a value and sets the error message on failure. */
254 bool
255 dfilter_fvalue_from_string(dfwork_t *dfw, ftenum_t ftype, stnode_t *st,
256 header_field_info *hfinfo_value_string)
258 fvalue_t *fv;
259 const GString *gs = stnode_string(st);
260 char *error_message = NULL;
261 enum mk_result res;
263 fv = fvalue_from_string(ftype, gs->str, gs->len, &error_message);
264 if (fv != NULL) {
265 g_free(error_message); // error_message is expected to be null
266 stnode_replace(st, STTYPE_FVALUE, fv);
267 return false;
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;
283 // Failure
284 dfw_set_error_location(dfw, stnode_location(st));
285 FAIL_HERE(dfw);
286 ws_assert_not_reached();
289 void
290 dfilter_fvalue_from_charconst(dfwork_t *dfw, ftenum_t ftype, stnode_t *st)
292 fvalue_t *fv;
293 unsigned long *nump = stnode_data(st);
294 char *error_message = NULL;
296 fv = fvalue_from_charconst(ftype, *nump, &error_message);
297 if (fv != NULL) {
298 g_free(error_message); // error_message is expected to be null
299 stnode_replace(st, STTYPE_FVALUE, fv);
300 return;
302 SET_ERROR(dfw, error_message);
304 // Failure
305 dfw_set_error_location(dfw, stnode_location(st));
306 FAIL_HERE(dfw);
307 ws_assert_not_reached();
310 void
311 dfilter_fvalue_from_number(dfwork_t *dfw, ftenum_t ftype, stnode_t *st)
313 fvalue_t *fv = NULL;
314 const char *s = stnode_token(st);
315 char *error_message = NULL;
316 stnumber_t num_type;
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). */
324 switch (num_type) {
325 case STNUM_INTEGER:
326 case STNUM_UNSIGNED:
327 ftype = FT_INT64;
328 break;
329 case STNUM_FLOAT:
330 ftype = FT_DOUBLE;
331 break;
332 case STNUM_NONE:
333 ws_assert_not_reached();
337 switch (num_type) {
338 case STNUM_INTEGER:
339 fv = fvalue_from_sinteger64(ftype, s, sttype_number_get_integer(st), &error_message);
340 break;
342 case STNUM_UNSIGNED:
343 fv = fvalue_from_uinteger64(ftype, s, sttype_number_get_unsigned(st), &error_message);
344 break;
346 case STNUM_FLOAT:
347 fv = fvalue_from_floating(ftype, s, sttype_number_get_float(st), &error_message);
348 break;
350 case STNUM_NONE:
351 ws_assert_not_reached();
354 if (fv != NULL) {
355 g_free(error_message); // error_message is expected to be null
356 stnode_replace(st, STTYPE_FVALUE, fv);
357 return;
359 SET_ERROR(dfw, error_message);
361 // Failure
362 dfw_set_error_location(dfw, stnode_location(st));
363 FAIL_HERE(dfw);
364 ws_assert_not_reached();
367 /* Creates a FT_BOOLEAN fvalue with a given value. */
368 static fvalue_t*
369 mk_boolean_fvalue(bool val)
371 fvalue_t *fv;
373 fv = fvalue_new(FT_BOOLEAN);
374 fvalue_set_uinteger64(fv, val);
376 return fv;
379 /* Creates a FT_STRING fvalue with a given value. */
380 static fvalue_t*
381 mk_string_fvalue(const char *str)
383 fvalue_t *fv = fvalue_new(FT_STRING);
384 fvalue_set_string(fv, str);
385 return fv;
388 /* Creates a FT_UINT64 fvalue with a given value. */
389 static fvalue_t*
390 mk_uint64_fvalue(uint64_t val)
392 fvalue_t *fv = fvalue_new(FT_UINT64);
393 fvalue_set_uinteger64(fv, val);
394 return fv;
397 static enum mk_result
398 mk_fvalue_from_hfinfo(const header_field_info *hfinfo, const char *s, uint64_t *valp)
400 /* Early return? */
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) {
409 case FT_NONE:
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:
417 case FT_IPv4:
418 case FT_IPv6:
419 case FT_IPXNET:
420 case FT_AX25:
421 case FT_VINES:
422 case FT_FCWWN:
423 case FT_ETHER:
424 case FT_BYTES:
425 case FT_UINT_BYTES:
426 case FT_STRING:
427 case FT_STRINGZ:
428 case FT_UINT_STRING:
429 case FT_STRINGZPAD:
430 case FT_STRINGZTRUNC:
431 case FT_EUI64:
432 case FT_GUID:
433 case FT_OID:
434 case FT_REL_OID:
435 case FT_SYSTEM_ID:
436 case FT_FRAMENUM: /* hfinfo->strings contains ft_framenum_type_t, not strings */
437 return MK_ERROR_BAD_TYPE;
439 case FT_BOOLEAN:
440 case FT_CHAR:
441 case FT_UINT8:
442 case FT_UINT16:
443 case FT_UINT24:
444 case FT_UINT32:
445 case FT_UINT40:
446 case FT_UINT48:
447 case FT_UINT56:
448 case FT_UINT64:
449 case FT_INT8:
450 case FT_INT16:
451 case FT_INT24:
452 case FT_INT32:
453 case FT_INT40:
454 case FT_INT48:
455 case FT_INT56:
456 case FT_INT64:
457 break;
459 case FT_NUM_TYPES:
460 case FT_SCALAR:
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) {
472 *valp = 1;
473 return MK_OK_BOOLEAN;
475 if (g_ascii_strcasecmp(s, tf->false_string) == 0) {
476 *valp = 0;
477 return MK_OK_BOOLEAN;
479 return MK_ERROR;
482 /* Do val_strings exist? */
483 if (!hfinfo->strings) {
484 return MK_ERROR_NO_STRINGS;
487 uint64_t val = 0, val_max = 0;
488 size_t count = 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;
497 count++;
499 vals++;
501 if (count > 1) {
502 // More than one match, use a string.
503 return MK_OK_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) {
509 *valp = val;
510 return MK_OK_NUMBER;
512 else {
513 return MK_OK_STRING;
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) {
524 val = vals->value;
525 count++;
527 vals++;
529 if (count > 1) {
530 // More than one match, use a string.
531 return MK_OK_STRING;
533 else if (count == 1) {
534 // Only one match, convert string to number.
535 *valp = val;
536 return MK_OK_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. */
544 return MK_OK_STRING;
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.
551 else {
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) {
558 val = vals->value;
559 count++;
561 vals++;
563 if (count > 1) {
564 // More than one match, use a string.
565 return MK_OK_STRING;
567 else if (count == 1) {
568 // Only one match, convert string to number.
569 *valp = val;
570 return MK_OK_NUMBER;
573 return MK_ERROR;
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)
586 fvalue_t *fv = NULL;
587 enum mk_result res;
588 uint64_t val;
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
610 * value strings.)
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);
621 switch (res) {
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. */
629 res = MK_OK_STRING;
630 } else {
631 res = MAX(res, prev_res);
633 break;
635 case MK_OK_BOOLEAN:
636 case MK_OK_NUMBER:
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
641 * a string match. */
642 res = MK_OK_STRING;
644 break;
646 case MK_OK_STRING:
647 break;
651 switch (res) {
653 case MK_OK_BOOLEAN:
654 fv = mk_boolean_fvalue((bool)val);
655 break;
657 case MK_OK_NUMBER:
658 fv = mk_uint64_fvalue(val);
659 break;
661 case MK_OK_STRING:
662 fv = mk_string_fvalue(s);
663 break;
665 case MK_ERROR_BAD_TYPE:
666 res = MK_ERROR;
667 break;
669 case MK_ERROR_NO_STRINGS:
670 dfilter_fail(dfw, DF_ERROR_GENERIC, stnode_location(st), "%s cannot accept strings as values.",
671 hfinfo->abbrev);
672 res = MK_ERROR;
673 break;
675 case MK_ERROR:
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),
682 s, hfinfo->abbrev);
683 } else {
684 dfilter_fail(dfw, DF_ERROR_GENERIC, stnode_location(st), "\"%s\" cannot be found among the possible values for %s.",
685 s, hfinfo->abbrev);
687 break;
690 if (fv) {
691 df_error_free(&dfw->error);
692 stnode_replace(st, STTYPE_FVALUE, fv);
695 return res;
698 static bool
699 is_bytes_type(enum ftenum type)
701 switch(type) {
702 case FT_VINES:
703 case FT_FCWWN:
704 case FT_ETHER:
705 case FT_BYTES:
706 case FT_UINT_BYTES:
707 case FT_IPv6:
708 case FT_OID:
709 case FT_REL_OID:
710 case FT_SYSTEM_ID:
711 case FT_EUI64:
712 return true;
714 case FT_NONE:
715 case FT_PROTOCOL:
716 case FT_FLOAT:
717 case FT_DOUBLE:
718 case FT_IEEE_11073_SFLOAT:
719 case FT_IEEE_11073_FLOAT:
720 case FT_ABSOLUTE_TIME:
721 case FT_RELATIVE_TIME:
722 case FT_IPv4:
723 case FT_IPXNET:
724 case FT_GUID:
725 case FT_STRING:
726 case FT_STRINGZ:
727 case FT_UINT_STRING:
728 case FT_STRINGZPAD:
729 case FT_STRINGZTRUNC:
730 case FT_AX25:
731 case FT_BOOLEAN:
732 case FT_FRAMENUM:
733 case FT_CHAR:
734 case FT_UINT8:
735 case FT_UINT16:
736 case FT_UINT24:
737 case FT_UINT32:
738 case FT_UINT40:
739 case FT_UINT48:
740 case FT_UINT56:
741 case FT_UINT64:
742 case FT_INT8:
743 case FT_INT16:
744 case FT_INT24:
745 case FT_INT32:
746 case FT_INT40:
747 case FT_INT48:
748 case FT_INT56:
749 case FT_INT64:
750 return false;
752 case FT_NUM_TYPES:
753 case FT_SCALAR:
754 ASSERT_FTYPE_NOT_REACHED(type);
757 ws_assert_not_reached();
758 return false;
761 static ftenum_t
762 get_slice_ftype(dfwork_t *dfw, stnode_t *st_node)
764 stnode_t *entity1 = sttype_slice_entity(st_node);
765 ws_assert(entity1);
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;
771 static ftenum_t
772 get_function_ftype(dfwork_t *dfw, stnode_t *st_node)
774 df_func_def_t *funcdef;
775 GSList *params;
776 unsigned nparams;
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;
784 if (nparams < 1)
785 return FT_NONE;
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) {
791 return ftype;
794 return FT_NONE;
797 ftenum_t
798 get_logical_ftype(dfwork_t *dfw, stnode_t *st_node)
800 stnode_t *st_arg1, *st_arg2;
801 ftenum_t ft;
803 switch(stnode_type_id(st_node)) {
804 case STTYPE_FIELD:
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);
812 case STTYPE_STRING:
813 case STTYPE_LITERAL:
814 case STTYPE_CHARCONST:
815 case STTYPE_NUMBER:
816 return FT_NONE;
818 case STTYPE_FUNCTION:
819 return get_function_ftype(dfw, st_node);
821 case STTYPE_ARITHMETIC:
822 case STTYPE_TEST:
823 sttype_oper_get(st_node, NULL, &st_arg1, &st_arg2);
824 if (st_arg1 && (ft = get_logical_ftype(dfw, st_arg1)) != FT_NONE)
825 return ft;
826 if (st_arg2 && (ft = get_logical_ftype(dfw, st_arg2)) != FT_NONE)
827 return ft;
828 return FT_NONE;
830 case STTYPE_SLICE:
831 return get_slice_ftype(dfw, st_node);
833 case STTYPE_SET:
834 case STTYPE_UNINITIALIZED:
835 case STTYPE_NUM_TYPES:
836 case STTYPE_FVALUE:
837 case STTYPE_PCRE:
838 ASSERT_STTYPE_NOT_REACHED(stnode_type_id(st_node));
841 ws_assert_not_reached();
844 static ftenum_t
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");
851 return ftype;
854 /* Check the semantics of an existence test. */
855 static ftenum_t
856 check_exists(dfwork_t *dfw, stnode_t *st_arg1)
858 ftenum_t ftype = FT_NONE;
859 resolve_unparsed(dfw, st_arg1, true);
861 LOG_NODE(st_arg1);
863 switch (stnode_type_id(st_arg1)) {
864 case STTYPE_FIELD:
865 dfw->field_count++;
866 /* fall-through */
867 case STTYPE_REFERENCE:
868 /* This is OK */
869 if (dfw->flags & DF_RETURN_VALUES) {
870 ftype = sttype_field_ftenum(st_arg1);
872 break;
873 case STTYPE_STRING:
874 case STTYPE_LITERAL:
875 case STTYPE_CHARCONST:
876 case STTYPE_NUMBER:
877 FAIL(dfw, st_arg1, "%s is neither a field nor a protocol name.",
878 stnode_todisplay(st_arg1));
879 break;
881 case STTYPE_UNPARSED:
882 case STTYPE_FUNCTION:
883 case STTYPE_SET:
884 case STTYPE_UNINITIALIZED:
885 case STTYPE_NUM_TYPES:
886 case STTYPE_TEST:
887 case STTYPE_FVALUE:
888 case STTYPE_PCRE:
889 case STTYPE_ARITHMETIC:
890 case STTYPE_SLICE:
891 ASSERT_STTYPE_NOT_REACHED(stnode_type_id(st_arg1));
894 return ftype;
897 ftenum_t
898 check_slice(dfwork_t *dfw, stnode_t *st, ftenum_t logical_ftype)
900 stnode_t *entity1;
901 header_field_info *hfinfo1;
902 sttype_id_t sttype1;
903 ftenum_t ftype1 = FT_NONE;
905 LOG_NODE(st);
907 entity1 = sttype_slice_entity(st);
908 ws_assert(entity1);
909 resolve_unparsed(dfw, entity1, true);
910 sttype1 = stnode_type_id(entity1);
912 switch (sttype1) {
913 case STTYPE_FIELD:
914 dfw->field_count++;
915 /* fall-through */
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));
924 break;
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));
933 break;
935 case STTYPE_SLICE:
936 ftype1 = check_slice(dfw, entity1, logical_ftype);
937 break;
939 case STTYPE_LITERAL:
940 case STTYPE_STRING:
941 case STTYPE_CHARCONST:
942 case STTYPE_NUMBER:
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:
949 case STTYPE_PCRE:
950 case STTYPE_FVALUE:
951 case STTYPE_TEST:
952 case STTYPE_ARITHMETIC:
953 case STTYPE_SET:
954 ASSERT_STTYPE_NOT_REACHED(sttype1);
958 return FT_IS_STRING(ftype1) ? FT_STRING : FT_BYTES;
961 static void
962 convert_to_bytes(stnode_t *arg)
964 stnode_t *entity1;
965 drange_node *rn;
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);
976 ftenum_t
977 check_function(dfwork_t *dfw, stnode_t *st_node, ftenum_t logical_ftype)
979 df_func_def_t *funcdef;
980 GSList *params;
981 unsigned nparams;
983 LOG_NODE(st_node);
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. */
1003 static void
1004 check_relation_LHS_FIELD(dfwork_t *dfw, stnode_op_t st_op,
1005 FtypeCanFunc can_func, bool allow_partial_value,
1006 stnode_t *st_node,
1007 stnode_t *st_arg1, stnode_t *st_arg2)
1009 sttype_id_t type2;
1010 header_field_info *hfinfo1;
1011 ftenum_t ftype1, ftype2;
1012 bool mk_val_string = false;
1014 LOG_NODE(st_node);
1016 if (stnode_type_id(st_arg1) == STTYPE_FIELD)
1017 dfw->field_count++;
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);
1031 else {
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) {
1055 dfw->field_count++;
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);
1071 else {
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.",
1107 hfinfo1->abbrev,
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));
1145 else {
1146 ASSERT_STTYPE_NOT_REACHED(type2);
1150 static void
1151 check_relation_LHS_FVALUE(dfwork_t *dfw, stnode_op_t st_op,
1152 FtypeCanFunc can_func, bool allow_partial_value,
1153 stnode_t *st_node,
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;
1159 ftenum_t ftype2;
1160 bool mk_val_string = false;
1162 LOG_NODE(st_node);
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) {
1175 dfw->field_count++;
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));
1209 else {
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);
1226 else {
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));
1242 static void
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)
1250 sttype_id_t type2;
1251 ftenum_t ftype1, ftype2;
1253 LOG_NODE(st_node);
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) {
1277 dfw->field_count++;
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));
1334 else {
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. */
1341 static void
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)
1347 sttype_id_t type2;
1348 ftenum_t ftype1, ftype2;
1350 LOG_NODE(st_node);
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) {
1375 dfw->field_count++;
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));
1444 else {
1445 ASSERT_STTYPE_NOT_REACHED(type2);
1449 static void
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)
1455 sttype_id_t type2;
1456 ftenum_t ftype1, ftype2;
1458 LOG_NODE(st_node);
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) {
1481 dfw->field_count++;
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));
1546 else {
1547 ASSERT_STTYPE_NOT_REACHED(type2);
1551 /* Check the semantics of any relational test. */
1552 static void
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);
1560 LOG_NODE(st_node);
1562 switch (stnode_type_id(st_arg1)) {
1563 case STTYPE_FIELD:
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);
1568 break;
1569 case STTYPE_SLICE:
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));
1572 break;
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));
1576 break;
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));
1580 break;
1581 case STTYPE_LITERAL:
1582 case STTYPE_STRING:
1583 case STTYPE_CHARCONST:
1584 case STTYPE_NUMBER:
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));
1587 break;
1588 case STTYPE_UNINITIALIZED:
1589 case STTYPE_PCRE:
1590 case STTYPE_FVALUE:
1591 case STTYPE_TEST:
1592 case STTYPE_SET:
1593 case STTYPE_NUM_TYPES:
1594 ASSERT_STTYPE_NOT_REACHED(stnode_type_id(st_arg1));
1598 static void
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);
1615 static void
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);
1622 LOG_NODE(st_node);
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)) {
1629 case STTYPE_FIELD:
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);
1634 break;
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));
1638 break;
1639 case STTYPE_SLICE:
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));
1642 break;
1643 default:
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));
1650 static void
1651 check_relation_matches(dfwork_t *dfw, stnode_t *st_node,
1652 stnode_t *st_arg1, stnode_t *st_arg2)
1654 ws_regex_t *pcre;
1655 char *errmsg = NULL;
1656 GString *patt;
1658 resolve_unparsed(dfw, st_arg1, true);
1660 LOG_NODE(st_node);
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);
1670 if (errmsg) {
1671 dfilter_fail(dfw, DF_ERROR_GENERIC, stnode_location(st_arg2), "Regex compilation error: %s.", errmsg);
1672 g_free(errmsg);
1673 ws_noisy("Semantic check failed here with a regex syntax error");
1674 THROW(TypeError);
1677 stnode_replace(st_arg2, STTYPE_PCRE, pcre);
1679 switch (stnode_type_id(st_arg1)) {
1680 case STTYPE_FIELD:
1681 case STTYPE_REFERENCE:
1682 check_relation_LHS_FIELD(dfw, STNODE_OP_MATCHES, ftype_can_matches,
1683 true, st_node, st_arg1, st_arg2);
1684 break;
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));
1688 break;
1689 case STTYPE_SLICE:
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));
1692 break;
1693 default:
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));
1699 static void
1700 check_relation_in(dfwork_t *dfw, stnode_t *st_node _U_,
1701 stnode_t *st_arg1, stnode_t *st_arg2)
1703 GSList *nodelist;
1704 stnode_t *node_left, *node_right;
1706 resolve_unparsed(dfw, st_arg1, true);
1707 resolve_unparsed(dfw, st_arg2, false);
1709 LOG_NODE(st_node);
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);
1722 while (nodelist) {
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.");
1729 break;
1732 nodelist = g_slist_next(nodelist);
1733 ws_assert(nodelist);
1734 node_right = nodelist->data;
1735 if (node_right) {
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);
1741 } else {
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 */
1750 static void
1751 check_test(dfwork_t *dfw, stnode_t *st_node)
1753 stnode_op_t st_op;
1754 stnode_t *st_arg1, *st_arg2;
1756 LOG_NODE(st_node);
1758 sttype_oper_get(st_node, &st_op, &st_arg1, &st_arg2);
1760 switch (st_op) {
1761 case STNODE_OP_NOT:
1762 semcheck(dfw, st_arg1);
1763 break;
1764 case STNODE_OP_AND:
1765 case STNODE_OP_OR:
1766 semcheck(dfw, st_arg1);
1767 semcheck(dfw, st_arg2);
1768 break;
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);
1774 break;
1775 case STNODE_OP_GT:
1776 case STNODE_OP_GE:
1777 case STNODE_OP_LT:
1778 case STNODE_OP_LE:
1779 check_relation(dfw, st_op, ftype_can_cmp, false, st_node, st_arg1, st_arg2);
1780 break;
1781 case STNODE_OP_CONTAINS:
1782 check_relation_contains(dfw, st_node, st_arg1, st_arg2);
1783 break;
1784 case STNODE_OP_MATCHES:
1785 check_relation_matches(dfw, st_node, st_arg1, st_arg2);
1786 break;
1787 case STNODE_OP_IN:
1788 case STNODE_OP_NOT_IN:
1789 check_relation_in(dfw, st_node, st_arg1, st_arg2);
1790 break;
1792 case STNODE_OP_UNINITIALIZED:
1793 case STNODE_OP_UNARY_MINUS:
1794 case STNODE_OP_BITWISE_AND:
1795 case STNODE_OP_ADD:
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);
1804 static ftenum_t
1805 check_nonzero(dfwork_t *dfw, stnode_t *st_node)
1807 ftenum_t ftype;
1809 LOG_NODE(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));
1814 break;
1815 case STTYPE_SLICE:
1816 ftype = check_slice(dfw, st_node, find_logical_ftype(dfw, st_node));
1817 break;
1818 case STTYPE_FUNCTION:
1819 ftype = check_function(dfw, st_node, find_logical_ftype(dfw, st_node));
1820 break;
1821 default:
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));
1830 return ftype;
1833 static const char *
1834 op_to_error_msg(stnode_op_t st_op)
1836 switch (st_op) {
1837 case STNODE_OP_UNARY_MINUS:
1838 return "cannot be negated";
1839 case STNODE_OP_ADD:
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";
1851 default:
1852 return "cannot FIXME";
1856 static void
1857 do_unary_minus(dfwork_t *dfw, stnode_t *st_node, stnode_t *st_arg1)
1859 char *err_msg;
1860 fvalue_t *new_fv = fvalue_unary_minus(stnode_data(st_arg1), &err_msg);
1861 if (new_fv == NULL)
1862 FAIL_MSG(dfw, st_node, err_msg);
1863 stnode_replace(st_node, STTYPE_FVALUE, new_fv);
1866 static void
1867 do_addition(dfwork_t *dfw, stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
1869 char *err_msg;
1870 fvalue_t *new_fv = fvalue_add(stnode_data(st_arg1), stnode_data(st_arg2), &err_msg);
1871 if (new_fv == NULL)
1872 FAIL_MSG(dfw, st_node, err_msg);
1873 stnode_replace(st_node, STTYPE_FVALUE, new_fv);
1876 static void
1877 do_subtraction(dfwork_t *dfw, stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
1879 char *err_msg;
1880 fvalue_t *new_fv = fvalue_subtract(stnode_data(st_arg1), stnode_data(st_arg2), &err_msg);
1881 if (new_fv == NULL)
1882 FAIL_MSG(dfw, st_node, err_msg);
1883 stnode_replace(st_node, STTYPE_FVALUE, new_fv);
1886 static void
1887 do_multiplication(dfwork_t *dfw, stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
1889 char *err_msg;
1890 fvalue_t *new_fv = fvalue_multiply(stnode_data(st_arg1), stnode_data(st_arg2), &err_msg);
1891 if (new_fv == NULL)
1892 FAIL_MSG(dfw, st_node, err_msg);
1893 stnode_replace(st_node, STTYPE_FVALUE, new_fv);
1896 static void
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");
1902 char *err_msg;
1903 fvalue_t *new_fv = fvalue_divide(stnode_data(st_arg1), stnode_data(st_arg2), &err_msg);
1904 if (new_fv == NULL)
1905 FAIL_MSG(dfw, st_node, err_msg);
1906 stnode_replace(st_node, STTYPE_FVALUE, new_fv);
1909 static void
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");
1915 char *err_msg;
1916 fvalue_t *new_fv = fvalue_modulo(stnode_data(st_arg1), stnode_data(st_arg2), &err_msg);
1917 if (new_fv == NULL)
1918 FAIL_MSG(dfw, st_node, err_msg);
1919 stnode_replace(st_node, STTYPE_FVALUE, new_fv);
1922 static void
1923 do_bitwise_and(dfwork_t *dfw, stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
1925 char *err_msg;
1926 fvalue_t *new_fv = fvalue_bitwise_and(stnode_data(st_arg1), stnode_data(st_arg2), &err_msg);
1927 if (new_fv == NULL)
1928 FAIL_MSG(dfw, st_node, err_msg);
1929 stnode_replace(st_node, STTYPE_FVALUE, new_fv);
1932 static ftenum_t
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;
1941 LOG_NODE(st_node);
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);
1953 return ftype1;
1956 switch (st_op) {
1957 case STNODE_OP_ADD:
1958 can_func = ftype_can_add;
1959 do_func = do_addition;
1960 break;
1961 case STNODE_OP_SUBTRACT:
1962 can_func = ftype_can_subtract;
1963 do_func = do_subtraction;
1964 break;
1965 case STNODE_OP_MULTIPLY:
1966 can_func = ftype_can_multiply;
1967 do_func = do_multiplication;
1968 break;
1969 case STNODE_OP_DIVIDE:
1970 can_func = ftype_can_divide;
1971 do_func = do_division;
1972 break;
1973 case STNODE_OP_MODULO:
1974 can_func = ftype_can_modulo;
1975 do_func = do_modulo;
1976 break;
1977 case STNODE_OP_BITWISE_AND:
1978 can_func = ftype_can_bitwise_and;
1979 do_func = do_bitwise_and;
1980 break;
1981 default:
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);
2009 return ftype1;
2013 * Time arithmetic with scalar multiplication/division only.
2014 * An extra limitation is that multiplicative scalars must appear on the
2015 * RHS currently.
2017 static ftenum_t
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);
2027 LOG_NODE(st_node);
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);
2034 return ftype1;
2037 switch (st_op) {
2038 case STNODE_OP_ADD:
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));
2048 break;
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));
2059 break;
2060 default:
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 */
2069 switch (st_op) {
2070 case STNODE_OP_ADD:
2071 do_func = do_addition;
2072 break;
2073 case STNODE_OP_SUBTRACT:
2074 do_func = do_subtraction;
2075 break;
2076 case STNODE_OP_MULTIPLY:
2077 do_func = do_multiplication;
2078 break;
2079 case STNODE_OP_DIVIDE:
2080 do_func = do_division;
2081 break;
2082 default:
2083 ASSERT_STNODE_OP_NOT_REACHED(st_op);
2085 do_func(dfw, st_node, st_arg1, st_arg2);
2088 return ftype1;
2091 ftenum_t
2092 check_arithmetic(dfwork_t *dfw, stnode_t *st_node, ftenum_t logical_ftype)
2094 sttype_id_t type;
2095 stnode_op_t st_op;
2096 stnode_t *st_arg1, *st_arg2;
2097 ftenum_t ftype = FT_NONE;
2099 LOG_NODE(st_node);
2101 resolve_unparsed(dfw, st_node, true);
2103 type = stnode_type_id(st_node);
2105 switch (type) {
2106 case STTYPE_LITERAL:
2107 dfilter_fvalue_from_literal(dfw, logical_ftype, st_node, false, NULL);
2108 ftype = sttype_pointer_ftenum(st_node);
2109 break;
2111 case STTYPE_STRING:
2112 dfilter_fvalue_from_string(dfw, logical_ftype, st_node, NULL);
2113 ftype = sttype_pointer_ftenum(st_node);
2114 break;
2116 case STTYPE_CHARCONST:
2117 dfilter_fvalue_from_charconst(dfw, logical_ftype, st_node);
2118 ftype = sttype_pointer_ftenum(st_node);
2119 break;
2121 case STTYPE_NUMBER:
2122 dfilter_fvalue_from_number(dfw, logical_ftype, st_node);
2123 ftype = sttype_pointer_ftenum(st_node);
2124 break;
2126 case STTYPE_FIELD:
2127 dfw->field_count++;
2128 /* fall-through */
2129 case STTYPE_REFERENCE:
2130 ftype = sttype_field_ftenum(st_node);
2131 break;
2133 case STTYPE_FUNCTION:
2134 ftype = check_function(dfw, st_node, logical_ftype);
2135 break;
2137 case STTYPE_SLICE:
2138 ftype = check_slice(dfw, st_node, logical_ftype);
2139 break;
2141 case STTYPE_FVALUE:
2142 ftype = sttype_pointer_ftenum(st_node);
2143 break;
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);
2149 else
2150 ftype = check_arithmetic_LHS_NUMBER(dfw, st_op, st_node, st_arg1, st_arg2, logical_ftype);
2151 break;
2153 case STTYPE_SET:
2154 case STTYPE_PCRE:
2155 case STTYPE_UNPARSED:
2156 case STTYPE_UNINITIALIZED:
2157 case STTYPE_NUM_TYPES:
2158 case STTYPE_TEST:
2159 ASSERT_STTYPE_NOT_REACHED(type);
2162 return ftype;
2166 /* Check the entire syntax tree. */
2167 static ftenum_t
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;
2176 LOG_NODE(st_node);
2178 dfw->field_count = 0;
2180 switch (stnode_type_id(st_node)) {
2181 case STTYPE_TEST:
2182 check_test(dfw, st_node);
2183 break;
2184 case STTYPE_ARITHMETIC:
2185 case STTYPE_SLICE:
2186 case STTYPE_FUNCTION:
2187 ftype = check_nonzero(dfw, st_node);
2188 break;
2189 default:
2190 ftype = check_exists(dfw, st_node);
2193 if (dfw->field_count == 0) {
2194 FAIL(dfw, st_node, "Constant expression is invalid.");
2197 return ftype;
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. */
2204 bool
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. */
2215 TRY {
2216 ftype = semcheck(dfw, dfw->st_root);
2218 CATCH(TypeError) {
2219 ok_filter = false;
2221 ENDTRY;
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;
2227 return ok_filter;
2231 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2233 * Local variables:
2234 * c-basic-offset: 8
2235 * tab-width: 8
2236 * indent-tabs-mode: t
2237 * End:
2239 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2240 * :indentSize=8:tabSize=8:noTabs=false: