diff options
-rw-r--r-- | docbook/release-notes.adoc | 1 | ||||
-rw-r--r-- | epan/dfilter/dfvm.c | 28 | ||||
-rw-r--r-- | epan/dfilter/semcheck.c | 61 | ||||
-rw-r--r-- | epan/ftypes/ftype-bytes.c | 54 | ||||
-rw-r--r-- | epan/ftypes/ftype-double.c | 20 | ||||
-rw-r--r-- | epan/ftypes/ftype-guid.c | 10 | ||||
-rw-r--r-- | epan/ftypes/ftype-ieee-11073-float.c | 28 | ||||
-rw-r--r-- | epan/ftypes/ftype-integer.c | 293 | ||||
-rw-r--r-- | epan/ftypes/ftype-ipv4.c | 13 | ||||
-rw-r--r-- | epan/ftypes/ftype-ipv6.c | 22 | ||||
-rw-r--r-- | epan/ftypes/ftype-none.c | 3 | ||||
-rw-r--r-- | epan/ftypes/ftype-protocol.c | 33 | ||||
-rw-r--r-- | epan/ftypes/ftype-string.c | 45 | ||||
-rw-r--r-- | epan/ftypes/ftype-time.c | 13 | ||||
-rw-r--r-- | epan/ftypes/ftypes-int.h | 17 | ||||
-rw-r--r-- | epan/ftypes/ftypes.c | 173 | ||||
-rw-r--r-- | epan/ftypes/ftypes.h | 63 |
17 files changed, 658 insertions, 219 deletions
diff --git a/docbook/release-notes.adoc b/docbook/release-notes.adoc index 2673f2d959..cceb4667e3 100644 --- a/docbook/release-notes.adoc +++ b/docbook/release-notes.adoc @@ -142,6 +142,7 @@ They previously shipped with Qt 5.12.2. This may be useful to match byte patterns but note that in general protocol fields with a string type still cannot contain embedded null bytes. ** Booleans can be written as True/TRUE or False/FALSE. Previously they could only be written as 1 or 0. ** It is now possible to test for the existence of a slice. +** All integer sizes are now compatible. Unless overflow occurs any integer field can be compared with any other. * The `text2pcap` command and the “Import from Hex Dump” feature have been updated and enhanced: ** `text2pcap` supports writing the output file in all the capture file formats that wiretap library supports, using the same `-F` option as `editcap`, `mergecap`, and `tshark`. diff --git a/epan/dfilter/dfvm.c b/epan/dfilter/dfvm.c index b794925c4a..fec5acb436 100644 --- a/epan/dfilter/dfvm.c +++ b/epan/dfilter/dfvm.c @@ -735,8 +735,8 @@ enum match_how { MATCH_ALL }; -typedef gboolean (*DFVMCompareFunc)(const fvalue_t*, const fvalue_t*); -typedef gboolean (*DFVMTestFunc)(const fvalue_t*); +typedef ft_bool_t (*DFVMCompareFunc)(const fvalue_t*, const fvalue_t*); +typedef ft_bool_t (*DFVMTestFunc)(const fvalue_t*); static gboolean cmp_test(enum match_how how, DFVMCompareFunc match_func, @@ -745,7 +745,7 @@ cmp_test(enum match_how how, DFVMCompareFunc match_func, GSList *list1, *list2; gboolean want_all = (how == MATCH_ALL); gboolean want_any = (how == MATCH_ANY); - gboolean have_match; + ft_bool_t have_match; list1 = arg1; @@ -753,10 +753,10 @@ cmp_test(enum match_how how, DFVMCompareFunc match_func, list2 = arg2; while (list2) { have_match = match_func(list1->data, list2->data); - if (want_all && !have_match) { + if (want_all && have_match == FT_FALSE) { return FALSE; } - else if (want_any && have_match) { + else if (want_any && have_match == FT_TRUE) { return TRUE; } list2 = g_slist_next(list2); @@ -773,16 +773,16 @@ cmp_test_unary(enum match_how how, DFVMTestFunc test_func, GSList *arg1) GSList *list1; gboolean want_all = (how == MATCH_ALL); gboolean want_any = (how == MATCH_ANY); - gboolean have_match; + ft_bool_t have_match; list1 = arg1; while (list1) { have_match = test_func(list1->data); - if (want_all && !have_match) { + if (want_all && have_match == FT_FALSE) { return FALSE; } - else if (want_any && have_match) { + else if (want_any && have_match == FT_TRUE) { return TRUE; } list1 = g_slist_next(list1); @@ -848,7 +848,7 @@ any_matches(dfilter_t *df, dfvm_value_t *arg1, dfvm_value_t *arg2) ws_regex_t *re = arg2->value.pcre; while (list1) { - if (fvalue_matches(list1->data, re)) { + if (fvalue_matches(list1->data, re) == FT_TRUE) { return TRUE; } list1 = g_slist_next(list1); @@ -863,7 +863,7 @@ all_matches(dfilter_t *df, dfvm_value_t *arg1, dfvm_value_t *arg2) ws_regex_t *re = arg2->value.pcre; while (list1) { - if (!fvalue_matches(list1->data, re)) { + if (fvalue_matches(list1->data, re) == FT_FALSE) { return FALSE; } list1 = g_slist_next(list1); @@ -875,8 +875,8 @@ static gboolean any_in_range_internal(GSList *list1, fvalue_t *low, fvalue_t *high) { while (list1) { - if (fvalue_ge(list1->data, low) && - fvalue_le(list1->data, high)) { + if (fvalue_ge(list1->data, low) == FT_TRUE && + fvalue_le(list1->data, high) == FT_TRUE) { return TRUE; } list1 = g_slist_next(list1); @@ -888,8 +888,8 @@ static gboolean all_in_range_internal(GSList *list1, fvalue_t *low, fvalue_t *high) { while (list1) { - if (!fvalue_ge(list1->data, low) || - !fvalue_le(list1->data, high)) { + if (fvalue_ge(list1->data, low) == FT_FALSE || + fvalue_le(list1->data, high) == FT_FALSE) { return FALSE; } list1 = g_slist_next(list1); diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c index fd267feadb..ed3ac77fcb 100644 --- a/epan/dfilter/semcheck.c +++ b/epan/dfilter/semcheck.c @@ -52,27 +52,26 @@ compatible_ftypes(ftenum_t a, ftenum_t b) { switch (a) { case FT_NONE: + case FT_BOOLEAN: case FT_PROTOCOL: - case FT_FLOAT: /* XXX - should be able to compare with INT */ - case FT_DOUBLE: /* XXX - should be able to compare with INT */ case FT_ABSOLUTE_TIME: case FT_RELATIVE_TIME: case FT_IEEE_11073_SFLOAT: case FT_IEEE_11073_FLOAT: case FT_IPv4: case FT_IPv6: - case FT_IPXNET: - case FT_INT40: /* XXX - should be able to compare with INT */ - case FT_UINT40: /* XXX - should be able to compare with INT */ - case FT_INT48: /* XXX - should be able to compare with INT */ - case FT_UINT48: /* XXX - should be able to compare with INT */ - case FT_INT56: /* XXX - should be able to compare with INT */ - case FT_UINT56: /* XXX - should be able to compare with INT */ - case FT_INT64: /* XXX - should be able to compare with INT */ - case FT_UINT64: /* XXX - should be able to compare with INT */ - case FT_EUI64: /* XXX - should be able to compare with INT */ return a == b; + case FT_FLOAT: /* XXX - should be able to compare with INT */ + case FT_DOUBLE: /* XXX - should be able to compare with INT */ + switch (b) { + case FT_FLOAT: + case FT_DOUBLE: + return TRUE; + default: + return FALSE; + } + case FT_ETHER: case FT_BYTES: case FT_UINT_BYTES: @@ -86,33 +85,33 @@ compatible_ftypes(ftenum_t a, ftenum_t b) return (b == FT_ETHER || b == FT_BYTES || b == FT_UINT_BYTES || b == FT_GUID || b == FT_OID || b == FT_AX25 || b == FT_VINES || b == FT_FCWWN || b == FT_REL_OID || b == FT_SYSTEM_ID); - case FT_BOOLEAN: - case FT_FRAMENUM: - case FT_CHAR: case FT_UINT8: case FT_UINT16: case FT_UINT24: case FT_UINT32: + case FT_CHAR: + case FT_FRAMENUM: + case FT_IPXNET: + return ftype_can_val_to_uinteger(b); + + case FT_UINT40: + case FT_UINT48: + case FT_UINT56: + case FT_UINT64: + case FT_EUI64: + return ftype_can_val_to_uinteger64(b); + case FT_INT8: case FT_INT16: case FT_INT24: case FT_INT32: - switch (b) { - case FT_BOOLEAN: - case FT_FRAMENUM: - case FT_CHAR: - case FT_UINT8: - case FT_UINT16: - case FT_UINT24: - case FT_UINT32: - case FT_INT8: - case FT_INT16: - case FT_INT24: - case FT_INT32: - return TRUE; - default: - return FALSE; - } + return ftype_can_val_to_sinteger(b); + + case FT_INT40: + case FT_INT48: + case FT_INT56: + case FT_INT64: + return ftype_can_val_to_sinteger64(b); case FT_STRING: case FT_STRINGZ: diff --git a/epan/ftypes/ftype-bytes.c b/epan/ftypes/ftype-bytes.c index 1a83da8335..719bae0f25 100644 --- a/epan/ftypes/ftype-bytes.c +++ b/epan/ftypes/ftype-bytes.c @@ -536,16 +536,18 @@ slice(fvalue_t *fv, GByteArray *bytes, guint offset, guint length) g_byte_array_append(bytes, data, length); } -static int -cmp_order(const fvalue_t *fv_a, const fvalue_t *fv_b) +static enum ft_result +cmp_order(const fvalue_t *fv_a, const fvalue_t *fv_b, int *cmp) { GByteArray *a = fv_a->value.bytes; GByteArray *b = fv_b->value.bytes; if (a->len != b->len) - return a->len < b->len ? -1 : 1; + *cmp = a->len < b->len ? -1 : 1; + else + *cmp = memcmp(a->data, b->data, a->len); - return memcmp(a->data, b->data, a->len); + return FT_OK; } static enum ft_result @@ -573,26 +575,29 @@ bytes_bitwise_and(fvalue_t *fv_dst, const fvalue_t *fv_a, const fvalue_t *fv_b, return FT_OK; } -static gboolean -cmp_contains(const fvalue_t *fv_a, const fvalue_t *fv_b) +static enum ft_result +cmp_contains(const fvalue_t *fv_a, const fvalue_t *fv_b, gboolean *contains) { GByteArray *a = fv_a->value.bytes; GByteArray *b = fv_b->value.bytes; if (ws_memmem(a->data, a->len, b->data, b->len)) { - return TRUE; + *contains = TRUE; } else { - return FALSE; + *contains = FALSE; } + + return FT_OK; } -static gboolean -cmp_matches(const fvalue_t *fv, const ws_regex_t *regex) +static enum ft_result +cmp_matches(const fvalue_t *fv, const ws_regex_t *regex, gboolean *matches) { GByteArray *a = fv->value.bytes; - return ws_regex_matches_length(regex, a->data, a->len); + *matches = ws_regex_matches_length(regex, a->data, a->len); + return FT_OK; } static gboolean @@ -628,6 +633,9 @@ ftype_register_bytes(void) bytes_from_charconst, /* val_from_charconst */ bytes_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_byte_array = bytes_fvalue_set }, /* union set_value */ { .get_value_bytes = bytes_fvalue_get }, /* union get_value */ @@ -661,6 +669,9 @@ ftype_register_bytes(void) NULL, /* val_from_charconst */ bytes_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_byte_array = bytes_fvalue_set }, /* union set_value */ { .get_value_bytes = bytes_fvalue_get }, /* union get_value */ @@ -694,6 +705,9 @@ ftype_register_bytes(void) NULL, /* val_from_charconst */ bytes_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_bytes = ax25_fvalue_set }, /* union set_value */ { .get_value_bytes = bytes_fvalue_get }, /* union get_value */ @@ -727,6 +741,9 @@ ftype_register_bytes(void) NULL, /* val_from_charconst */ bytes_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_bytes = vines_fvalue_set }, /* union set_value */ { .get_value_bytes = bytes_fvalue_get }, /* union get_value */ @@ -760,6 +777,9 @@ ftype_register_bytes(void) NULL, /* val_from_charconst */ bytes_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_bytes = ether_fvalue_set }, /* union set_value */ { .get_value_bytes = bytes_fvalue_get }, /* union get_value */ @@ -793,6 +813,9 @@ ftype_register_bytes(void) NULL, /* val_from_charconst */ oid_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_byte_array = oid_fvalue_set }, /* union set_value */ { .get_value_bytes = bytes_fvalue_get }, /* union get_value */ @@ -826,6 +849,9 @@ ftype_register_bytes(void) NULL, /* val_from_charconst */ rel_oid_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_byte_array = oid_fvalue_set }, /* union set_value */ { .get_value_bytes = bytes_fvalue_get }, /* union get_value */ @@ -859,6 +885,9 @@ ftype_register_bytes(void) NULL, /* val_from_charconst */ system_id_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_byte_array = system_id_fvalue_set }, /* union set_value */ { .get_value_bytes = bytes_fvalue_get }, /* union get_value */ @@ -892,6 +921,9 @@ ftype_register_bytes(void) NULL, /* val_from_charconst */ bytes_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_bytes = fcwwn_fvalue_set }, /* union set_value */ { .get_value_bytes = bytes_fvalue_get }, /* union get_value */ diff --git a/epan/ftypes/ftype-double.c b/epan/ftypes/ftype-double.c index 4792e67d94..07ed61fcd3 100644 --- a/epan/ftypes/ftype-double.c +++ b/epan/ftypes/ftype-double.c @@ -120,14 +120,16 @@ val_divide(fvalue_t * dst, const fvalue_t *a, const fvalue_t *b, char **err_ptr return FT_OK; } -static int -cmp_order(const fvalue_t *a, const fvalue_t *b) +static enum ft_result +cmp_order(const fvalue_t *a, const fvalue_t *b, int *cmp) { if (a->value.floating < b->value.floating) - return -1; - if (a->value.floating > b->value.floating) - return 1; - return 0; + *cmp = -1; + else if (a->value.floating > b->value.floating) + *cmp = 1; + else + *cmp = 0; + return FT_OK; } static gboolean @@ -159,6 +161,9 @@ ftype_register_double(void) NULL, /* val_from_charconst */ float_val_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_floating = double_fvalue_set_floating }, /* union set_value */ { .get_value_floating = value_get_floating }, /* union get_value */ @@ -192,6 +197,9 @@ ftype_register_double(void) NULL, /* val_from_charconst */ double_val_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_floating = double_fvalue_set_floating }, /* union set_value */ { .get_value_floating = value_get_floating }, /* union get_value */ diff --git a/epan/ftypes/ftype-guid.c b/epan/ftypes/ftype-guid.c index 9f83fb4664..f884da38ab 100644 --- a/epan/ftypes/ftype-guid.c +++ b/epan/ftypes/ftype-guid.c @@ -87,10 +87,11 @@ guid_to_repr(wmem_allocator_t *scope, const fvalue_t *fv, ftrepr_t rtype _U_, in return guid_to_str(scope, &fv->value.guid); } -static int -cmp_order(const fvalue_t *a, const fvalue_t *b) +static enum ft_result +cmp_order(const fvalue_t *a, const fvalue_t *b, int *cmp) { - return memcmp(&a->value.guid, &b->value.guid, sizeof(e_guid_t)); + *cmp = memcmp(&a->value.guid, &b->value.guid, sizeof(e_guid_t)); + return FT_OK; } void @@ -110,6 +111,9 @@ ftype_register_guid(void) NULL, /* val_from_charconst */ guid_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_guid = guid_fvalue_set_guid }, /* union set_value */ { .get_value_guid = value_get }, /* union get_value */ diff --git a/epan/ftypes/ftype-ieee-11073-float.c b/epan/ftypes/ftype-ieee-11073-float.c index 5488f9a76b..bdeed362a6 100644 --- a/epan/ftypes/ftype-ieee-11073-float.c +++ b/epan/ftypes/ftype-ieee-11073-float.c @@ -444,12 +444,15 @@ sfloat_ieee_11073_cmp_lt(const fvalue_t *a, const fvalue_t *b) return FALSE; } -static int -sfloat_ieee_11073_cmp_order(const fvalue_t *a, const fvalue_t *b) +static enum ft_result +sfloat_ieee_11073_cmp_order(const fvalue_t *a, const fvalue_t *b, int *cmp) { if (sfloat_ieee_11073_cmp_lt(a, b)) - return -1; - return sfloat_ieee_11073_cmp_eq(a, b) ? 0 : 1; + *cmp = -1; + else + *cmp = sfloat_ieee_11073_cmp_eq(a, b) ? 0 : 1; + + return FT_OK; } static gboolean @@ -853,12 +856,15 @@ float_ieee_11073_cmp_lt(const fvalue_t *a, const fvalue_t *b) return FALSE; } -static int -float_ieee_11073_cmp_order(const fvalue_t *a, const fvalue_t *b) +static enum ft_result +float_ieee_11073_cmp_order(const fvalue_t *a, const fvalue_t *b, int *cmp) { if (float_ieee_11073_cmp_lt(a, b)) - return -1; - return float_ieee_11073_cmp_eq(a, b) ? 0 : 1; + *cmp = -1; + else + *cmp = float_ieee_11073_cmp_eq(a, b) ? 0 : 1; + + return FT_OK; } static gboolean @@ -911,6 +917,9 @@ Example: 114 is 0x0072 NULL, /* val_from_charconst */ sfloat_ieee_11073_val_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_uinteger = sfloat_ieee_11073_value_set }, /* union set_value */ { .get_value_uinteger = sfloat_ieee_11073_value_get }, /* union get_value */ @@ -971,6 +980,9 @@ Example: 36.4 is 0xFF00016C NULL, /* val_from_charconst */ float_ieee_11073_val_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_uinteger = float_ieee_11073_value_set }, /* union set_value */ { .get_value_uinteger = float_ieee_11073_value_get }, /* union get_value */ diff --git a/epan/ftypes/ftype-integer.c b/epan/ftypes/ftype-integer.c index 3c856a8b18..b611fd71a2 100644 --- a/epan/ftypes/ftype-integer.c +++ b/epan/ftypes/ftype-integer.c @@ -386,36 +386,60 @@ ipxnet_to_repr(wmem_allocator_t *scope, const fvalue_t *fv, ftrepr_t rtype, int return uinteger_to_repr(scope, fv, rtype, BASE_HEX); } -static int -uinteger_cmp_order(const fvalue_t *a, const fvalue_t *b) +static enum ft_result +uint64_cmp_order(const fvalue_t *a, const fvalue_t *b, int *cmp) { - if (a->value.uinteger == b->value.uinteger) - return 0; - return a->value.uinteger < b->value.uinteger ? -1 : 1; + guint64 val_a, val_b; + enum ft_result res; + + res = fvalue_to_uinteger64(a, &val_a); + if (res != FT_OK) + return res; + + res = fvalue_to_uinteger64(b, &val_b); + if (res != FT_OK) + return res; + + if (val_a == val_b) + *cmp = 0; + else + *cmp = val_a < val_b ? -1 : 1; + + return FT_OK; } -static int -sinteger_cmp_order(const fvalue_t *a, const fvalue_t *b) +static enum ft_result +uint_cmp_order(const fvalue_t *a, const fvalue_t *b, int *cmp) { - if (a->value.sinteger == b->value.sinteger) - return 0; - return a->value.sinteger < b->value.sinteger ? -1 : 1; + return uint64_cmp_order(a, b, cmp); } -static int -uinteger64_cmp_order(const fvalue_t *a, const fvalue_t *b) +static enum ft_result +sint64_cmp_order(const fvalue_t *a, const fvalue_t *b, int *cmp) { - if (a->value.uinteger64 == b->value.uinteger64) - return 0; - return a->value.uinteger64 < b->value.uinteger64 ? -1 : 1; + gint64 val_a, val_b; + enum ft_result res; + + res = fvalue_to_sinteger64(a, &val_a); + if (res != FT_OK) + return res; + + res = fvalue_to_sinteger64(b, &val_b); + if (res != FT_OK) + return res; + + if (val_a == val_b) + *cmp = 0; + else + *cmp = val_a < val_b ? -1 : 1; + + return FT_OK; } -static int -sinteger64_cmp_order(const fvalue_t *a, const fvalue_t *b) +static enum ft_result +sint_cmp_order(const fvalue_t *a, const fvalue_t *b, int *cmp) { - if (a->value.sinteger64 == b->value.sinteger64) - return 0; - return a->value.sinteger64 < b->value.sinteger64 ? -1 : 1; + return sint64_cmp_order(a, b, cmp); } static void @@ -666,26 +690,26 @@ uinteger64_to_repr(wmem_allocator_t *scope, const fvalue_t *fv, ftrepr_t rtype _ return result; } -enum ft_result +static enum ft_result uint_bitwise_and(fvalue_t *dst, const fvalue_t *a, const fvalue_t *b, char **err_ptr _U_) { dst->value.uinteger = a->value.uinteger & b->value.uinteger; return FT_OK; } -gboolean +static gboolean uint_is_zero(const fvalue_t *fv) { return fv->value.uinteger == 0; } -gboolean +static gboolean uint_is_negative(const fvalue_t *fv _U_) { return FALSE; } -enum ft_result +static enum ft_result uint_unary_minus(fvalue_t *dst, const fvalue_t *src, char **err_ptr) { /* Unsigned integers are promoted to signed 32 bits. */ @@ -700,26 +724,26 @@ uint_unary_minus(fvalue_t *dst, const fvalue_t *src, char **err_ptr) return FT_OK; } -enum ft_result +static enum ft_result uint64_bitwise_and(fvalue_t *dst, const fvalue_t *a, const fvalue_t *b, char **err_ptr _U_) { dst->value.uinteger64 = a->value.uinteger64 & b->value.uinteger64; return FT_OK; } -gboolean +static gboolean uint64_is_zero(const fvalue_t *fv) { return fv->value.uinteger64 == 0; } -gboolean +static gboolean uint64_is_negative(const fvalue_t *fv _U_) { return FALSE; } -enum ft_result +static enum ft_result uint64_unary_minus(fvalue_t *dst, const fvalue_t *src, char **err_ptr) { /* Unsigned64 integers are promoted to signed 64 bits. */ @@ -734,52 +758,52 @@ uint64_unary_minus(fvalue_t *dst, const fvalue_t *src, char **err_ptr) return FT_OK; } -enum ft_result +static enum ft_result sint_bitwise_and(fvalue_t *dst, const fvalue_t *a, const fvalue_t *b, char **err_ptr _U_) { dst->value.sinteger = a->value.sinteger & b->value.sinteger; return FT_OK; } -gboolean +static gboolean sint_is_zero(const fvalue_t *fv) { return fv->value.sinteger == 0; } -gboolean +static gboolean sint_is_negative(const fvalue_t *fv) { return fv->value.sinteger < 0; } -enum ft_result +static enum ft_result sint_unary_minus(fvalue_t * dst, const fvalue_t *src, char **err_ptr _U_) { dst->value.sinteger = -src->value.sinteger; return FT_OK; } -enum ft_result +static enum ft_result sint64_bitwise_and(fvalue_t *dst, const fvalue_t *a, const fvalue_t *b, char **err_ptr _U_) { dst->value.sinteger64 = a->value.sinteger64 & b->value.sinteger64; return FT_OK; } -gboolean +static gboolean sint64_is_zero(const fvalue_t *fv) { return fv->value.sinteger64 == 0; } -gboolean +static gboolean sint64_is_negative(const fvalue_t *fv) { return fv->value.sinteger64 < 0; } -enum ft_result +static enum ft_result sint64_unary_minus(fvalue_t * dst, const fvalue_t *src, char **err_ptr _U_) { dst->value.sinteger64 = -src->value.sinteger64; @@ -1060,6 +1084,66 @@ uint64_modulo(fvalue_t *dst, const fvalue_t *a, const fvalue_t *b, char **err_pt return FT_OK; } +static enum ft_result uint_val_to_uinteger64(const fvalue_t *src, guint64 *dst) +{ + *dst = src->value.uinteger; + return FT_OK; +} + +static enum ft_result uint_val_to_sinteger64(const fvalue_t *src, gint64 *dst) +{ + *dst = (gint64)src->value.uinteger; + return FT_OK; +} + +static enum ft_result sint_val_to_uinteger64(const fvalue_t *src, guint64 *dst) +{ + if (src->value.sinteger < 0) + return FT_OVERFLOW; + + *dst = (guint64)src->value.sinteger; + return FT_OK; +} + +static enum ft_result sint_val_to_sinteger64(const fvalue_t *src, gint64 *dst) +{ + *dst = src->value.sinteger; + return FT_OK; +} + +static enum ft_result uint64_val_to_uinteger64(const fvalue_t *src, guint64 *dst) +{ + if (src->value.sinteger < 0) + return FT_OVERFLOW; + + *dst = (guint64)src->value.sinteger; + return FT_OK; +} + +static enum ft_result uint64_val_to_sinteger64(const fvalue_t *src, gint64 *dst) +{ + if (src->value.uinteger64 > G_MAXINT64) + return FT_OVERFLOW; + + *dst = (gint64)src->value.uinteger64; + return FT_OK; +} + +static enum ft_result sint64_val_to_uinteger64(const fvalue_t *src, guint64 *dst) +{ + if (src->value.sinteger64 < 0) + return FT_OVERFLOW; + + *dst = (guint64)src->value.sinteger64; + return FT_OK; +} + +static enum ft_result sint64_val_to_sinteger64(const fvalue_t *src, gint64 *dst) +{ + *dst = src->value.sinteger64; + return FT_OK; +} + /* BOOLEAN-specific */ static gboolean @@ -1092,19 +1176,33 @@ boolean_to_repr(wmem_allocator_t *scope, const fvalue_t *fv, ftrepr_t rtype _U_, * F T -1 * T F 1 */ -static int -boolean_cmp_order(const fvalue_t *a, const fvalue_t *b) +static enum ft_result +boolean_cmp_order(const fvalue_t *a, const fvalue_t *b, int *cmp) { - if (a->value.uinteger64) { - if (b->value.uinteger64) { - return 0; + guint64 val_a, val_b; + enum ft_result res; + + val_a = a->value.uinteger64; + res = fvalue_to_uinteger64(b, &val_b); + if (res != FT_OK) + return res; + + if (val_a) { + if (val_b) { + *cmp = 0; } - return 1; + else { + *cmp = 1; + } + } + else if (val_b) { + *cmp = -1; } - if (b->value.uinteger64) { - return -1; + else { + *cmp = 0; } - return 0; + + return FT_OK; } /* EUI64-specific */ @@ -1174,10 +1272,13 @@ ftype_register_integers(void) uint_from_charconst, /* val_from_charconst */ char_to_repr, /* val_to_string_repr */ + uint_val_to_uinteger64, /* val_to_uinteger64 */ + uint_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_uinteger = set_uinteger }, /* union set_value */ { .get_value_uinteger = get_uinteger }, /* union get_value */ - uinteger_cmp_order, + uint_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ @@ -1206,10 +1307,13 @@ ftype_register_integers(void) uint_from_charconst, /* val_from_charconst */ uinteger_to_repr, /* val_to_string_repr */ + uint_val_to_uinteger64, /* val_to_uinteger64 */ + uint_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_uinteger = set_uinteger }, /* union set_value */ { .get_value_uinteger = get_uinteger }, /* union get_value */ - uinteger_cmp_order, + uint_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ @@ -1238,10 +1342,13 @@ ftype_register_integers(void) uint_from_charconst, /* val_from_charconst */ uinteger_to_repr, /* val_to_string_repr */ + uint_val_to_uinteger64, /* val_to_uinteger64 */ + uint_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_uinteger = set_uinteger }, /* union set_value */ { .get_value_uinteger = get_uinteger }, /* union get_value */ - uinteger_cmp_order, + uint_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ @@ -1270,10 +1377,13 @@ ftype_register_integers(void) uint_from_charconst, /* val_from_charconst */ uinteger_to_repr, /* val_to_string_repr */ + uint_val_to_uinteger64, /* val_to_uinteger64 */ + uint_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_uinteger = set_uinteger }, /* union set_value */ { .get_value_uinteger = get_uinteger }, /* union get_value */ - uinteger_cmp_order, + uint_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ @@ -1302,10 +1412,13 @@ ftype_register_integers(void) uint_from_charconst, /* val_from_charconst */ uinteger_to_repr, /* val_to_string_repr */ + uint_val_to_uinteger64, /* val_to_uinteger64 */ + uint_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_uinteger = set_uinteger }, /* union set_value */ { .get_value_uinteger = get_uinteger }, /* union get_value */ - uinteger_cmp_order, + uint_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ @@ -1334,10 +1447,13 @@ ftype_register_integers(void) uint64_from_charconst, /* val_from_charconst */ uinteger64_to_repr, /* val_to_string_repr */ + uint64_val_to_uinteger64, /* val_to_uinteger64 */ + uint64_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_uinteger64 = set_uinteger64 }, /* union set_value */ { .get_value_uinteger64 = get_uinteger64 }, /* union get_value */ - uinteger64_cmp_order, + uint64_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ @@ -1366,10 +1482,13 @@ ftype_register_integers(void) uint64_from_charconst, /* val_from_charconst */ uinteger64_to_repr, /* val_to_string_repr */ + uint64_val_to_uinteger64, /* val_to_uinteger64 */ + uint64_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_uinteger64 = set_uinteger64 }, /* union set_value */ { .get_value_uinteger64 = get_uinteger64 }, /* union get_value */ - uinteger64_cmp_order, + uint64_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ @@ -1398,10 +1517,13 @@ ftype_register_integers(void) uint64_from_charconst, /* val_from_charconst */ uinteger64_to_repr, /* val_to_string_repr */ + uint64_val_to_uinteger64, /* val_to_uinteger64 */ + uint64_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_uinteger64 = set_uinteger64 }, /* union set_value */ { .get_value_uinteger64 = get_uinteger64 }, /* union get_value */ - uinteger64_cmp_order, + uint64_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ @@ -1430,10 +1552,13 @@ ftype_register_integers(void) uint64_from_charconst, /* val_from_charconst */ uinteger64_to_repr, /* val_to_string_repr */ + uint64_val_to_uinteger64, /* val_to_uinteger64 */ + uint64_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_uinteger64 = set_uinteger64 }, /* union set_value */ { .get_value_uinteger64 = get_uinteger64 }, /* union get_value */ - uinteger64_cmp_order, + uint64_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ @@ -1462,10 +1587,13 @@ ftype_register_integers(void) sint_from_charconst, /* val_from_charconst */ integer_to_repr, /* val_to_string_repr */ + sint_val_to_uinteger64, /* val_to_uinteger64 */ + sint_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_sinteger = set_sinteger }, /* union set_value */ { .get_value_sinteger = get_sinteger }, /* union get_value */ - sinteger_cmp_order, + sint_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ @@ -1494,10 +1622,13 @@ ftype_register_integers(void) sint_from_charconst, /* val_from_charconst */ integer_to_repr, /* val_to_string_repr */ + sint_val_to_uinteger64, /* val_to_uinteger64 */ + sint_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_sinteger = set_sinteger }, /* union set_value */ { .get_value_sinteger = get_sinteger }, /* union get_value */ - sinteger_cmp_order, + sint_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ @@ -1526,10 +1657,13 @@ ftype_register_integers(void) sint_from_charconst, /* val_from_charconst */ integer_to_repr, /* val_to_string_repr */ + sint_val_to_uinteger64, /* val_to_uinteger64 */ + sint_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_sinteger = set_sinteger }, /* union set_value */ { .get_value_sinteger = get_sinteger }, /* union get_value */ - sinteger_cmp_order, + sint_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ @@ -1558,10 +1692,13 @@ ftype_register_integers(void) sint_from_charconst, /* val_from_charconst */ integer_to_repr, /* val_to_string_repr */ + sint_val_to_uinteger64, /* val_to_uinteger64 */ + sint_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_sinteger = set_sinteger }, /* union set_value */ { .get_value_sinteger = get_sinteger }, /* union get_value */ - sinteger_cmp_order, + sint_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ @@ -1590,10 +1727,13 @@ ftype_register_integers(void) sint64_from_charconst, /* val_from_charconst */ integer64_to_repr, /* val_to_string_repr */ + sint64_val_to_uinteger64, /* val_to_uinteger64 */ + sint64_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_sinteger64 = set_sinteger64 }, /* union set_value */ { .get_value_sinteger64 = get_sinteger64 }, /* union get_value */ - sinteger64_cmp_order, + sint64_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ @@ -1622,10 +1762,13 @@ ftype_register_integers(void) sint64_from_charconst, /* val_from_charconst */ integer64_to_repr, /* val_to_string_repr */ + sint64_val_to_uinteger64, /* val_to_uinteger64 */ + sint64_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_sinteger64 = set_sinteger64 }, /* union set_value */ { .get_value_sinteger64 = get_sinteger64 }, /* union get_value */ - sinteger64_cmp_order, + sint64_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ @@ -1654,10 +1797,13 @@ ftype_register_integers(void) sint64_from_charconst, /* val_from_charconst */ integer64_to_repr, /* val_to_string_repr */ + sint64_val_to_uinteger64, /* val_to_uinteger64 */ + sint64_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_sinteger64 = set_sinteger64 }, /* union set_value */ { .get_value_sinteger64 = get_sinteger64 }, /* union get_value */ - sinteger64_cmp_order, + sint64_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ @@ -1686,10 +1832,13 @@ ftype_register_integers(void) sint64_from_charconst, /* val_from_charconst */ integer64_to_repr, /* val_to_string_repr */ + sint64_val_to_uinteger64, /* val_to_uinteger64 */ + sint64_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_sinteger64 = set_sinteger64 }, /* union set_value */ { .get_value_sinteger64 = get_sinteger64 }, /* union get_value */ - sinteger64_cmp_order, + sint64_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ @@ -1718,10 +1867,13 @@ ftype_register_integers(void) uint64_from_charconst, /* val_from_charconst */ boolean_to_repr, /* val_to_string_repr */ + uint64_val_to_uinteger64, /* val_to_uinteger64 */ + uint64_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_uinteger64 = set_uinteger64 }, /* union set_value */ { .get_value_uinteger64 = get_uinteger64 }, /* union get_value */ - boolean_cmp_order, /* cmp_eq */ + boolean_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ @@ -1751,10 +1903,13 @@ ftype_register_integers(void) NULL, /* val_from_charconst */ ipxnet_to_repr, /* val_to_string_repr */ + uint_val_to_uinteger64, /* val_to_uinteger64 */ + uint_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_uinteger = set_uinteger }, /* union set_value */ { .get_value_uinteger = get_uinteger }, /* union get_value */ - uinteger_cmp_order, + uint_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ @@ -1784,10 +1939,13 @@ ftype_register_integers(void) uint_from_charconst, /* val_from_charconst */ uinteger_to_repr, /* val_to_string_repr */ + uint_val_to_uinteger64, /* val_to_uinteger64 */ + uint_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_uinteger = set_uinteger }, /* union set_value */ { .get_value_uinteger = get_uinteger }, /* union get_value */ - uinteger_cmp_order, + uint_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ @@ -1817,10 +1975,13 @@ ftype_register_integers(void) NULL, /* val_from_charconst */ eui64_to_repr, /* val_to_string_repr */ + uint64_val_to_uinteger64, /* val_to_uinteger64 */ + uint64_val_to_sinteger64, /* val_to_sinteger64 */ + { .set_value_uinteger64 = set_uinteger64 }, /* union set_value */ { .get_value_uinteger64 = get_uinteger64 }, /* union get_value */ - uinteger64_cmp_order, + uint64_cmp_order, /* cmp_order */ NULL, /* cmp_contains */ NULL, /* cmp_matches */ diff --git a/epan/ftypes/ftype-ipv4.c b/epan/ftypes/ftype-ipv4.c index eff2c6f154..b9b5f85138 100644 --- a/epan/ftypes/ftype-ipv4.c +++ b/epan/ftypes/ftype-ipv4.c @@ -109,8 +109,8 @@ val_to_repr(wmem_allocator_t *scope, const fvalue_t *fv, ftrepr_t rtype _U_, int * So, for example, w.x.y.z/32 eq w.x.y.0/24 is TRUE. */ -static int -cmp_order(const fvalue_t *fv_a, const fvalue_t *fv_b) +static enum ft_result +cmp_order(const fvalue_t *fv_a, const fvalue_t *fv_b, int *cmp) { guint32 addr_a, addr_b, nmask; @@ -118,8 +118,10 @@ cmp_order(const fvalue_t *fv_a, const fvalue_t *fv_b) addr_a = fv_a->value.ipv4.addr & nmask; addr_b = fv_b->value.ipv4.addr & nmask; if (addr_a == addr_b) - return 0; - return addr_a < addr_b ? -1 : 1; + *cmp = 0; + else + *cmp = addr_a < addr_b ? -1 : 1; + return FT_OK; } static enum ft_result @@ -162,6 +164,9 @@ ftype_register_ipv4(void) NULL, /* val_from_charconst */ val_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_uinteger = set_uinteger }, /* union set_value */ { .get_value_uinteger = value_get }, /* union get_value */ diff --git a/epan/ftypes/ftype-ipv6.c b/epan/ftypes/ftype-ipv6.c index c21a827a42..75daf13f30 100644 --- a/epan/ftypes/ftype-ipv6.c +++ b/epan/ftypes/ftype-ipv6.c @@ -94,8 +94,8 @@ value_get(fvalue_t *fv) static const guint8 bitmasks[9] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; -static int -cmp_order(const fvalue_t *fv_a, const fvalue_t *fv_b) +static enum ft_result +cmp_order(const fvalue_t *fv_a, const fvalue_t *fv_b, int *cmp) { const ipv6_addr_and_prefix *a = &(fv_a->value.ipv6); const ipv6_addr_and_prefix *b = &(fv_b->value.ipv6); @@ -109,8 +109,10 @@ cmp_order(const fvalue_t *fv_a, const fvalue_t *fv_b) gint byte_a = (gint) (a->addr.bytes[pos]); gint byte_b = (gint) (b->addr.bytes[pos]); - if (byte_a != byte_b) - return byte_a - byte_b; + if (byte_a != byte_b) { + *cmp = byte_a - byte_b; + return FT_OK; + } prefix -= 8; pos++; @@ -120,10 +122,13 @@ cmp_order(const fvalue_t *fv_a, const fvalue_t *fv_b) gint byte_a = (gint) (a->addr.bytes[pos] & (bitmasks[prefix])); gint byte_b = (gint) (b->addr.bytes[pos] & (bitmasks[prefix])); - if (byte_a != byte_b) - return byte_a - byte_b; + if (byte_a != byte_b) { + *cmp = byte_a - byte_b; + return FT_OK; + } } - return 0; + *cmp = 0; + return FT_OK; } static enum ft_result @@ -185,6 +190,9 @@ ftype_register_ipv6(void) NULL, /* val_from_charconst */ ipv6_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_bytes = ipv6_fvalue_set }, /* union set_value */ { .get_value_bytes = value_get }, /* union get_value */ diff --git a/epan/ftypes/ftype-none.c b/epan/ftypes/ftype-none.c index 4e02b9b54c..7b65cf98d2 100644 --- a/epan/ftypes/ftype-none.c +++ b/epan/ftypes/ftype-none.c @@ -28,6 +28,9 @@ ftype_register_none(void) NULL, /* val_from_charconst */ NULL, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { NULL }, /* union set_value */ { NULL }, /* union get_value */ diff --git a/epan/ftypes/ftype-protocol.c b/epan/ftypes/ftype-protocol.c index 8cdd19c9de..25571e3407 100644 --- a/epan/ftypes/ftype-protocol.c +++ b/epan/ftypes/ftype-protocol.c @@ -267,8 +267,8 @@ _tvbcmp(const protocol_value_t *a, const protocol_value_t *b) return memcmp(tvb_get_ptr(a->tvb, 0, a_len), tvb_get_ptr(b->tvb, 0, a_len), a_len); } -static int -cmp_order(const fvalue_t *fv_a, const fvalue_t *fv_b) +static enum ft_result +cmp_order(const fvalue_t *fv_a, const fvalue_t *fv_b, int *cmp) { const protocol_value_t *a = (const protocol_value_t *)&fv_a->value.protocol; const protocol_value_t *b = (const protocol_value_t *)&fv_b->value.protocol; @@ -286,25 +286,26 @@ cmp_order(const fvalue_t *fv_a, const fvalue_t *fv_b) } ENDTRY; - return c; + *cmp = c; + return FT_OK; } -static gboolean -cmp_contains(const fvalue_t *fv_a, const fvalue_t *fv_b) +static enum ft_result +cmp_contains(const fvalue_t *fv_a, const fvalue_t *fv_b, gboolean *contains) { - volatile gboolean contains = FALSE; + volatile gboolean yes = FALSE; TRY { /* First see if tvb exists for both sides */ if ((fv_a->value.protocol.tvb != NULL) && (fv_b->value.protocol.tvb != NULL)) { if (tvb_find_tvb(fv_a->value.protocol.tvb, fv_b->value.protocol.tvb, 0) > -1) { - contains = TRUE; + yes = TRUE; } } else { /* Otherwise just compare strings */ if ((strlen(fv_b->value.protocol.proto_string) != 0) && strstr(fv_a->value.protocol.proto_string, fv_b->value.protocol.proto_string)) { - contains = TRUE; + yes = TRUE; } } } @@ -313,11 +314,12 @@ cmp_contains(const fvalue_t *fv_a, const fvalue_t *fv_b) } ENDTRY; - return contains; + *contains = yes; + return FT_OK; } -static gboolean -cmp_matches(const fvalue_t *fv, const ws_regex_t *regex) +static enum ft_result +cmp_matches(const fvalue_t *fv, const ws_regex_t *regex, gboolean *matches) { const protocol_value_t *a = (const protocol_value_t *)&fv->value.protocol; volatile gboolean rc = FALSE; @@ -325,7 +327,7 @@ cmp_matches(const fvalue_t *fv, const ws_regex_t *regex) guint32 tvb_len; /* tvb length */ if (! regex) { - return FALSE; + return FT_BADARG; } TRY { if (a->tvb != NULL) { @@ -340,7 +342,9 @@ cmp_matches(const fvalue_t *fv, const ws_regex_t *regex) rc = FALSE; } ENDTRY; - return rc; + + *matches = rc; + return FT_OK; } static gboolean @@ -367,6 +371,9 @@ ftype_register_tvbuff(void) val_from_charconst, /* val_from_charconst */ val_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_protocol = value_set }, /* union set_value */ { .get_value_protocol = value_get }, /* union get_value */ diff --git a/epan/ftypes/ftype-string.c b/epan/ftypes/ftype-string.c index 51a8b11b5d..c2789a2422 100644 --- a/epan/ftypes/ftype-string.c +++ b/epan/ftypes/ftype-string.c @@ -134,40 +134,46 @@ slice(fvalue_t *fv, GByteArray *bytes, guint offset, guint length) g_byte_array_append(bytes, data, length); } -static int -cmp_order(const fvalue_t *a, const fvalue_t *b) +static enum ft_result +cmp_order(const fvalue_t *a, const fvalue_t *b, int *cmp) { - return wmem_strbuf_strcmp(a->value.strbuf, b->value.strbuf); + *cmp = wmem_strbuf_strcmp(a->value.strbuf, b->value.strbuf); + return FT_OK; } -static gboolean -cmp_contains(const fvalue_t *fv_a, const fvalue_t *fv_b) +static enum ft_result +cmp_contains(const fvalue_t *fv_a, const fvalue_t *fv_b, gboolean *contains) { /* According to * http://www.introl.com/introl-demo/Libraries/C/ANSI_C/string/strstr.html * strstr() returns a non-NULL value if needle is an empty * string. We don't that behavior for cmp_contains. */ if (fv_b->value.strbuf->len == 0) { - return FALSE; + *contains = FALSE; + return FT_OK; } if (wmem_strbuf_strstr(fv_a->value.strbuf, fv_b->value.strbuf)) { - return TRUE; + *contains = TRUE; } else { - return FALSE; + *contains = FALSE; } + + return FT_OK; } -static gboolean -cmp_matches(const fvalue_t *fv, const ws_regex_t *regex) +static enum ft_result +cmp_matches(const fvalue_t *fv, const ws_regex_t *regex, gboolean *matches) { wmem_strbuf_t *buf = fv->value.strbuf; if (regex == NULL) { - return FALSE; + return FT_BADARG; } - return ws_regex_matches_length(regex, buf->str, buf->len); + + *matches = ws_regex_matches_length(regex, buf->str, buf->len); + return FT_OK; } void @@ -187,6 +193,9 @@ ftype_register_string(void) val_from_charconst, /* val_from_charconst */ string_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_strbuf = string_fvalue_set_strbuf }, /* union set_value */ { .get_value_strbuf = value_get }, /* union get_value */ @@ -219,6 +228,9 @@ ftype_register_string(void) val_from_charconst, /* val_from_charconst */ string_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_strbuf = string_fvalue_set_strbuf }, /* union set_value */ { .get_value_strbuf = value_get }, /* union get_value */ @@ -251,6 +263,9 @@ ftype_register_string(void) val_from_charconst, /* val_from_charconst */ string_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_strbuf = string_fvalue_set_strbuf }, /* union set_value */ { .get_value_strbuf = value_get }, /* union get_value */ @@ -283,6 +298,9 @@ ftype_register_string(void) val_from_charconst, /* val_from_charconst */ string_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_strbuf = string_fvalue_set_strbuf }, /* union set_value */ { .get_value_strbuf = value_get }, /* union get_value */ @@ -315,6 +333,9 @@ ftype_register_string(void) val_from_charconst, /* val_from_charconst */ string_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_strbuf = string_fvalue_set_strbuf }, /* union set_value */ { .get_value_strbuf = value_get }, /* union get_value */ diff --git a/epan/ftypes/ftype-time.c b/epan/ftypes/ftype-time.c index 34a39cc1eb..e35d426784 100644 --- a/epan/ftypes/ftype-time.c +++ b/epan/ftypes/ftype-time.c @@ -17,10 +17,11 @@ #include <wsutil/time_util.h> -static int -cmp_order(const fvalue_t *a, const fvalue_t *b) +static enum ft_result +cmp_order(const fvalue_t *a, const fvalue_t *b, int *cmp) { - return nstime_cmp(&(a->value.time), &(b->value.time)); + *cmp = nstime_cmp(&(a->value.time), &(b->value.time)); + return FT_OK; } /* @@ -462,6 +463,9 @@ ftype_register_time(void) NULL, /* val_from_charconst */ absolute_val_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_time = time_fvalue_set }, /* union set_value */ { .get_value_time = value_get }, /* union get_value */ @@ -494,6 +498,9 @@ ftype_register_time(void) NULL, /* val_from_charconst */ relative_val_to_repr, /* val_to_string_repr */ + NULL, /* val_to_uinteger64 */ + NULL, /* val_to_sinteger64 */ + { .set_value_time = time_fvalue_set }, /* union set_value */ { .get_value_time = value_get }, /* union get_value */ diff --git a/epan/ftypes/ftypes-int.h b/epan/ftypes/ftypes-int.h index ac782eaa9d..9a2b1e15b6 100644 --- a/epan/ftypes/ftypes-int.h +++ b/epan/ftypes/ftypes-int.h @@ -22,11 +22,6 @@ extern ftype_t* type_list[FT_NUM_TYPES]; ws_assert(ftype < FT_NUM_TYPES); \ result = type_list[ftype]; -enum ft_result { - FT_OK, - FT_ERROR, -}; - typedef void (*FvalueNewFunc)(fvalue_t*); typedef void (*FvalueCopyFunc)(fvalue_t*, const fvalue_t*); typedef void (*FvalueFreeFunc)(fvalue_t*); @@ -36,6 +31,9 @@ typedef gboolean (*FvalueFromString)(fvalue_t*, const char*, size_t, gchar **); typedef gboolean (*FvalueFromCharConst)(fvalue_t*, unsigned long, gchar **); typedef char *(*FvalueToStringRepr)(wmem_allocator_t *, const fvalue_t*, ftrepr_t, int field_display); +typedef enum ft_result (*FvalueToUnsignedInteger64Func)(const fvalue_t*, guint64 *); +typedef enum ft_result (*FvalueToSignedInteger64Func)(const fvalue_t*, gint64 *); + typedef void (*FvalueSetByteArrayFunc)(fvalue_t*, GByteArray *); typedef void (*FvalueSetBytesFunc)(fvalue_t*, const guint8 *); typedef void (*FvalueSetGuidFunc)(fvalue_t*, const e_guid_t *); @@ -59,9 +57,9 @@ typedef guint64 (*FvalueGetUnsignedInteger64Func)(fvalue_t*); typedef gint64 (*FvalueGetSignedInteger64Func)(fvalue_t*); typedef double (*FvalueGetFloatingFunc)(fvalue_t*); -typedef int (*FvalueCmp)(const fvalue_t*, const fvalue_t*); -typedef gboolean (*FvalueContains)(const fvalue_t*, const fvalue_t*); -typedef gboolean (*FvalueMatches)(const fvalue_t*, const ws_regex_t*); +typedef enum ft_result (*FvalueCmp)(const fvalue_t*, const fvalue_t*, int*); +typedef enum ft_result (*FvalueContains)(const fvalue_t*, const fvalue_t*, gboolean*); +typedef enum ft_result (*FvalueMatches)(const fvalue_t*, const ws_regex_t*, gboolean*); typedef gboolean (*FvalueIs)(const fvalue_t*); typedef guint (*FvalueLen)(fvalue_t*); @@ -82,6 +80,9 @@ struct _ftype_t { FvalueFromCharConst val_from_charconst; FvalueToStringRepr val_to_string_repr; + FvalueToUnsignedInteger64Func val_to_uinteger64; + FvalueToSignedInteger64Func val_to_sinteger64; + union { FvalueSetByteArrayFunc set_value_byte_array; FvalueSetBytesFunc set_value_bytes; diff --git a/epan/ftypes/ftypes.c b/epan/ftypes/ftypes.c index 0b18a19ff0..fbb2a4a690 100644 --- a/epan/ftypes/ftypes.c +++ b/epan/ftypes/ftypes.c @@ -299,6 +299,44 @@ ftype_can_is_negative(enum ftenum ftype) return ft->is_negative ? TRUE : FALSE; } +gboolean +ftype_can_val_to_sinteger(enum ftenum ftype) +{ + ftype_t *ft; + + FTYPE_LOOKUP(ftype, ft); + /* We first convert to 64 bit and then check for overflow. */ + return ft->val_to_sinteger64 ? TRUE : FALSE; +} + +gboolean +ftype_can_val_to_uinteger(enum ftenum ftype) +{ + ftype_t *ft; + + FTYPE_LOOKUP(ftype, ft); + /* We first convert to 64 bit and then check for overflow. */ + return ft->val_to_uinteger64 ? TRUE : FALSE; +} + +gboolean +ftype_can_val_to_sinteger64(enum ftenum ftype) +{ + ftype_t *ft; + + FTYPE_LOOKUP(ftype, ft); + return ft->val_to_sinteger64 ? TRUE : FALSE; +} + +gboolean +ftype_can_val_to_uinteger64(enum ftenum ftype) +{ + ftype_t *ft; + + FTYPE_LOOKUP(ftype, ft); + return ft->val_to_uinteger64 ? TRUE : FALSE; +} + /* ---------------------------------------------------------- */ /* Allocate and initialize an fvalue_t, given an ftype */ @@ -486,6 +524,46 @@ fvalue_to_string_repr(wmem_allocator_t *scope, const fvalue_t *fv, ftrepr_t rtyp return fv->ftype->val_to_string_repr(scope, fv, rtype, field_display); } +enum ft_result +fvalue_to_uinteger(const fvalue_t *fv, guint32 *repr) +{ + guint64 val; + enum ft_result res = fv->ftype->val_to_uinteger64(fv, &val); + if (res != FT_OK) + return res; + if (val > G_MAXUINT32) + return FT_OVERFLOW; + + *repr = (guint32)val; + return FT_OK; +} + +enum ft_result +fvalue_to_sinteger(const fvalue_t *fv, gint32 *repr) +{ + gint64 val; + enum ft_result res = fv->ftype->val_to_sinteger64(fv, &val); + if (res != FT_OK) + return res; + if (val > G_MAXINT32) + return FT_OVERFLOW; + + *repr = (gint32)val; + return FT_OK; +} + +enum ft_result +fvalue_to_uinteger64(const fvalue_t *fv, guint64 *repr) +{ + return fv->ftype->val_to_uinteger64(fv, repr); +} + +enum ft_result +fvalue_to_sinteger64(const fvalue_t *fv, gint64 *repr) +{ + return fv->ftype->val_to_sinteger64(fv, repr); +} + typedef struct { fvalue_t *fv; GByteArray *bytes; @@ -830,63 +908,108 @@ fvalue_get_floating(fvalue_t *fv) return fv->ftype->get_value.get_value_floating(fv); } -static inline int -_fvalue_cmp(const fvalue_t *a, const fvalue_t *b) -{ - /* XXX - check compatibility of a and b */ - ws_assert(a->ftype->cmp_order); - return a->ftype->cmp_order(a, b); -} - -gboolean +ft_bool_t fvalue_eq(const fvalue_t *a, const fvalue_t *b) { - return _fvalue_cmp(a, b) == 0; + int cmp; + enum ft_result res; + + ws_assert(a->ftype->cmp_order); + res = a->ftype->cmp_order(a, b, &cmp); + if (res != FT_OK) + return -res; + return cmp == 0 ? FT_TRUE : FT_FALSE; } -gboolean +ft_bool_t fvalue_ne(const fvalue_t *a, const fvalue_t *b) { - return _fvalue_cmp(a, b) != 0; + int cmp; + enum ft_result res; + + ws_assert(a->ftype->cmp_order); + res = a->ftype->cmp_order(a, b, &cmp); + if (res != FT_OK) + return -res; + return cmp != 0 ? FT_TRUE : FT_FALSE; } -gboolean +ft_bool_t fvalue_gt(const fvalue_t *a, const fvalue_t *b) { - return _fvalue_cmp(a, b) > 0; + int cmp; + enum ft_result res; + + ws_assert(a->ftype->cmp_order); + res = a->ftype->cmp_order(a, b, &cmp); + if (res != FT_OK) + return -res; + return cmp > 0 ? FT_TRUE : FT_FALSE; } -gboolean +ft_bool_t fvalue_ge(const fvalue_t *a, const fvalue_t *b) { - return _fvalue_cmp(a, b) >= 0; + int cmp; + enum ft_result res; + + ws_assert(a->ftype->cmp_order); + res = a->ftype->cmp_order(a, b, &cmp); + if (res != FT_OK) + return -res; + return cmp >= 0 ? FT_TRUE : FT_FALSE; } -gboolean +ft_bool_t fvalue_lt(const fvalue_t *a, const fvalue_t *b) { - return _fvalue_cmp(a, b) < 0; + int cmp; + enum ft_result res; + + ws_assert(a->ftype->cmp_order); + res = a->ftype->cmp_order(a, b, &cmp); + if (res != FT_OK) + return -res; + return cmp < 0 ? FT_TRUE : FT_FALSE; } -gboolean +ft_bool_t fvalue_le(const fvalue_t *a, const fvalue_t *b) { - return _fvalue_cmp(a, b) <= 0; + int cmp; + enum ft_result res; + + ws_assert(a->ftype->cmp_order); + res = a->ftype->cmp_order(a, b, &cmp); + if (res != FT_OK) + return -res; + return cmp <= 0 ? FT_TRUE : FT_FALSE; } -gboolean +ft_bool_t fvalue_contains(const fvalue_t *a, const fvalue_t *b) { - /* XXX - check compatibility of a and b */ + gboolean yes; + enum ft_result res; + ws_assert(a->ftype->cmp_contains); - return a->ftype->cmp_contains(a, b); + res = a->ftype->cmp_contains(a, b, &yes); + if (res != FT_OK) + return -res; + return yes ? FT_TRUE : FT_FALSE; } -gboolean +ft_bool_t fvalue_matches(const fvalue_t *a, const ws_regex_t *re) { + gboolean yes; + enum ft_result res; + ws_assert(a->ftype->cmp_matches); - return a->ftype->cmp_matches(a, re); + res = a->ftype->cmp_matches(a, re, &yes); + if (res != FT_OK) + return -res; + return yes ? FT_TRUE : FT_FALSE; } gboolean diff --git a/epan/ftypes/ftypes.h b/epan/ftypes/ftypes.h index 6064f6474d..3f8c3375d6 100644 --- a/epan/ftypes/ftypes.h +++ b/epan/ftypes/ftypes.h @@ -139,6 +139,25 @@ typedef enum ft_framenum_type ft_framenum_type_t; struct _ftype_t; typedef struct _ftype_t ftype_t; +enum ft_result { + FT_OK = 0, + FT_OVERFLOW, + FT_BADARG, + FT_ERROR, /* Generic. */ +}; + +/* + * True, false or error if negative. + * Note that + * ft_bool == FT_FALSE + * and + * ft_bool != FT_TRUE + * are different results (three-state logic). + */ +typedef int ft_bool_t; +#define FT_TRUE 1 +#define FT_FALSE 0 + /* String representation types. */ enum ftrepr { FTREPR_DISPLAY, @@ -226,6 +245,22 @@ WS_DLL_PUBLIC gboolean ftype_can_is_negative(enum ftenum ftype); +WS_DLL_PUBLIC +gboolean +ftype_can_val_to_sinteger(enum ftenum ftype); + +WS_DLL_PUBLIC +gboolean +ftype_can_val_to_uinteger(enum ftenum ftype); + +WS_DLL_PUBLIC +gboolean +ftype_can_val_to_sinteger64(enum ftenum ftype); + +WS_DLL_PUBLIC +gboolean +ftype_can_val_to_uinteger64(enum ftenum ftype); + /* ---------------- FVALUE ----------------- */ #include <epan/ipv4.h> @@ -305,6 +340,18 @@ fvalue_to_string_repr(wmem_allocator_t *scope, const fvalue_t *fv, ftrepr_t rtyp #define fvalue_to_debug_repr(scope, fv) \ fvalue_to_string_repr(scope, fv, FTREPR_DFILTER, 0) +WS_DLL_PUBLIC enum ft_result +fvalue_to_uinteger(const fvalue_t *fv, guint32 *repr); + +WS_DLL_PUBLIC enum ft_result +fvalue_to_sinteger(const fvalue_t *fv, gint32 *repr); + +WS_DLL_PUBLIC enum ft_result +fvalue_to_uinteger64(const fvalue_t *fv, guint64 *repr); + +WS_DLL_PUBLIC enum ft_result +fvalue_to_sinteger64(const fvalue_t *fv, gint64 *repr); + WS_DLL_PUBLIC ftenum_t fvalue_type_ftenum(fvalue_t *fv); @@ -388,28 +435,28 @@ fvalue_get_sinteger64(fvalue_t *fv); WS_DLL_PUBLIC double fvalue_get_floating(fvalue_t *fv); -gboolean +ft_bool_t fvalue_eq(const fvalue_t *a, const fvalue_t *b); -gboolean +ft_bool_t fvalue_ne(const fvalue_t *a, const fvalue_t *b); -gboolean +ft_bool_t fvalue_gt(const fvalue_t *a, const fvalue_t *b); -gboolean +ft_bool_t fvalue_ge(const fvalue_t *a, const fvalue_t *b); -gboolean +ft_bool_t fvalue_lt(const fvalue_t *a, const fvalue_t *b); -gboolean +ft_bool_t fvalue_le(const fvalue_t *a, const fvalue_t *b); -gboolean +ft_bool_t fvalue_contains(const fvalue_t *a, const fvalue_t *b); -gboolean +ft_bool_t fvalue_matches(const fvalue_t *a, const ws_regex_t *re); gboolean |