diff options
-rw-r--r-- | configure.in | 1 | ||||
-rw-r--r-- | epan/dfilter/semcheck.c | 14 | ||||
-rw-r--r-- | epan/ftypes/ftype-bytes.c | 36 | ||||
-rw-r--r-- | epan/ftypes/ftype-pcre.c | 151 | ||||
-rw-r--r-- | epan/ftypes/ftype-string.c | 35 | ||||
-rw-r--r-- | epan/ftypes/ftype-tvbuff.c | 53 | ||||
-rw-r--r-- | epan/ftypes/ftypes-int.h | 2 | ||||
-rw-r--r-- | epan/ftypes/ftypes.h | 2 | ||||
-rw-r--r-- | gtk/dfilter_expr_dlg.c | 6 | ||||
-rw-r--r-- | version_info.c | 2 |
10 files changed, 278 insertions, 24 deletions
diff --git a/configure.in b/configure.in index f5aca03941..6efc9bcc8b 100644 --- a/configure.in +++ b/configure.in @@ -1087,6 +1087,7 @@ AC_ARG_WITH(pcre, ],[ # # Use libpcre if it's present, otherwise don't. + # XXX - Should GLib 2.14 take precedence here? # want_pcre=ifavailable pcre_dir= diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c index 46c3b9fc52..5b083e5f2a 100644 --- a/epan/dfilter/semcheck.c +++ b/epan/dfilter/semcheck.c @@ -436,7 +436,7 @@ check_function(stnode_t *st_node) df_func_def_t *funcdef; GSList *params; guint iparam; - guint nparams; + guint nparams; funcdef = sttype_function_funcdef(st_node); params = sttype_function_params(st_node); @@ -588,7 +588,7 @@ check_relation_LHS_FIELD(const char *relation_string, FtypeCanFunc can_func, if (!compatible_ftypes(ftype1, ftype2)) { dfilter_fail("%s (type=%s) and return value of %s() (type=%s) are not of compatible types.", - hfinfo1->abbrev, ftype_pretty_name(ftype1), + hfinfo1->abbrev, ftype_pretty_name(ftype1), funcdef->name, ftype_pretty_name(ftype2)); THROW(TypeError); } @@ -674,7 +674,7 @@ check_relation_LHS_STRING(const char* relation_string, if (!can_func(ftype2)) { dfilter_fail("Return value of function %s (type=%s) cannot participate in '%s' comparison.", - funcdef->name, ftype_pretty_name(ftype2), + funcdef->name, ftype_pretty_name(ftype2), relation_string); THROW(TypeError); } @@ -770,7 +770,7 @@ check_relation_LHS_UNPARSED(const char* relation_string, s = stnode_data(st_arg1); fvalue = fvalue_from_unparsed(ftype2, s, allow_partial_value, dfilter_fail); - + if (!fvalue) { THROW(TypeError); } @@ -882,7 +882,7 @@ check_relation_LHS_RANGE(const char *relation_string, FtypeCanFunc can_func _U_, else if (type2 == STTYPE_FUNCTION) { funcdef = sttype_function_funcdef(st_arg2); ftype2 = funcdef->retval_ftype; - + if (!is_bytes_type(ftype2)) { if (!ftype_can_slice(ftype2)) { dfilter_fail("Return value of function \"%s\" is a %s and cannot be converted into a sequence of bytes.", @@ -1174,7 +1174,7 @@ check_test(stnode_t *st_node) check_relation("contains", TRUE, ftype_can_contains, st_node, st_arg1, st_arg2); break; case TEST_OP_MATCHES: -#ifdef HAVE_LIBPCRE +#if defined(HAVE_LIBPCRE) || GLIB_CHECK_VERSION(2,14,0) check_relation("matches", TRUE, ftype_can_matches, st_node, st_arg1, st_arg2); #else dfilter_fail("This Wireshark version does not support the \"matches\" operation."); @@ -1219,7 +1219,7 @@ dfw_semcheck(dfwork_t *dfw) #ifdef DEBUG_dfilter static guint i = 0; #endif - + DebugLog(("1 dfw_semcheck(dfwork_t *dfw = %p) [%u]\n", dfw, i)); /* Instead of having to check for errors at every stage of * the semantic-checking, the semantic-checking code will diff --git a/epan/ftypes/ftype-bytes.c b/epan/ftypes/ftype-bytes.c index d408158a67..d6a26dfef7 100644 --- a/epan/ftypes/ftype-bytes.c +++ b/epan/ftypes/ftype-bytes.c @@ -32,8 +32,10 @@ #include <epan/strutil.h> #include <epan/oids.h> -#ifdef HAVE_LIBPCRE -#include <pcre.h> +#if defined(HAVE_LIBPCRE) || GLIB_CHECK_VERSION(2,14,0) +# ifdef HAVE_LIBPCRE +# include <pcre.h> +# endif #define CMP_MATCHES cmp_matches #else #define CMP_MATCHES NULL @@ -504,7 +506,35 @@ cmp_matches(fvalue_t *fv_a, fvalue_t *fv_b) } return FALSE; } -#endif +#elif GLIB_CHECK_VERSION(2,14,0) /* GRegex */ +static gboolean +cmp_matches(fvalue_t *fv_a, fvalue_t *fv_b) +{ + GByteArray *a = fv_a->value.bytes; + GRegex *regex = fv_b->value.re; + + /* fv_b is always a FT_PCRE, otherwise the dfilter semcheck() would have + * warned us. For the same reason (and because we're using g_malloc()), + * fv_b->value.re is not NULL. + */ + if (strcmp(fv_b->ftype->name, "FT_PCRE") != 0) { + return FALSE; + } + if (! regex) { + return FALSE; + } + return g_regex_match_full( + regex, /* Compiled PCRE */ + a->data, /* The data to check for the pattern... */ + (int)a->len, /* ... and its length */ + 0, /* Start offset within data */ + G_REGEX_RAW, /* GRegexMatchFlags */ + NULL, /* We are not interested in the match information */ + NULL /* We don't want error information */ + ); + /* NOTE - DO NOT g_free(data) */ +} +#endif /* HAVE_LIBPCRE / GRegex */ void ftype_register_bytes(void) diff --git a/epan/ftypes/ftype-pcre.c b/epan/ftypes/ftype-pcre.c index 2edd34b8bf..4201dc75c4 100644 --- a/epan/ftypes/ftype-pcre.c +++ b/epan/ftypes/ftype-pcre.c @@ -216,7 +216,142 @@ ftype_register_pcre(void) ftype_register(FT_PCRE, &pcre_type); } -#else /* HAVE_LIBPCRE */ +#elif GLIB_CHECK_VERSION(2,14,0) /* No HAVE_LIBPCRE. Try falling back to GRegex. */ + + +#include <glib.h> +#include <string.h> + +static void +gregex_fvalue_new(fvalue_t *fv) +{ + fv->value.re = NULL; +} + +static void +gregex_fvalue_free(fvalue_t *fv) +{ + if (fv->value.re) { + g_regex_unref(fv->value.re); + fv->value.re = NULL; + } +} + +/* Generate a FT_PCRE from a parsed string pattern. + * Uses the specified logfunc() to report errors. */ +static gboolean +val_from_string(fvalue_t *fv, char *pattern, LogFunc logfunc) +{ + GError *regex_error = NULL; + /* Free up the old value, if we have one */ + gregex_fvalue_free(fv); + + fv->value.re = g_regex_new( + pattern, /* pattern */ + G_REGEX_OPTIMIZE, /* Compile options (G_REGEX_OPTIMIZE = pcre_study) */ + 0, /* Match options */ + ®ex_error /* Compile / study errors */ + ); + + if (regex_error) { + if (logfunc) { + logfunc(regex_error->message); + } + g_error_free(regex_error); + if (fv->value.re) { + g_regex_unref(fv->value.re); + } + return FALSE; + } + return TRUE; +} + +/* Generate a FT_PCRE from an unparsed string pattern. + * Uses the specified logfunc() to report errors. */ +static gboolean +val_from_unparsed(fvalue_t *fv, char *pattern, gboolean allow_partial_value _U_, LogFunc logfunc) +{ + g_assert(! allow_partial_value); + + return val_from_string(fv, pattern, logfunc); +} + +static int +gregex_repr_len(fvalue_t *fv, ftrepr_t rtype) +{ + g_assert(rtype == FTREPR_DFILTER); + return (int)strlen(g_regex_get_pattern(fv->value.re)); +} + +static void +gregex_to_repr(fvalue_t *fv, ftrepr_t rtype, char *buf) +{ + g_assert(rtype == FTREPR_DFILTER); + strcpy(buf, g_regex_get_pattern(fv->value.re)); +} + +/* BEHOLD - value contains the string representation of the regular expression, + * and we want to store the compiled PCRE RE object into the value. */ +static void +gregex_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied) +{ + g_assert(value != NULL); + /* Free up the old value, if we have one */ + gregex_fvalue_free(fv); + g_assert(! already_copied); + val_from_unparsed(fv, value, FALSE, NULL); +} + +static gpointer +gregex_fvalue_get(fvalue_t *fv) +{ + return fv->value.re; +} + +void +ftype_register_pcre(void) +{ + static ftype_t pcre_type = { + FT_PCRE, /* ftype */ + "FT_PCRE", /* name */ + "Compiled Perl-Compatible Regular Expression (GRegex) object", /* pretty_name */ + 0, /* wire_size */ + gregex_fvalue_new, /* new_value */ + gregex_fvalue_free, /* free_value */ + val_from_unparsed, /* val_from_unparsed */ + val_from_string, /* val_from_string */ + gregex_to_repr, /* val_to_string_repr */ + gregex_repr_len, /* len_string_repr */ + + gregex_fvalue_set, /* set_value */ + NULL, /* set_value_uinteger */ + NULL, /* set_value_sinteger */ + NULL, /* set_value_integer64 */ + NULL, /* set_value_floating */ + + gregex_fvalue_get, /* get_value */ + NULL, /* get_value_uinteger */ + NULL, /* get_value_sinteger */ + NULL, /* get_value_integer64 */ + NULL, /* get_value_floating */ + + NULL, /* cmp_eq */ + NULL, /* cmp_ne */ + NULL, /* cmp_gt */ + NULL, /* cmp_ge */ + NULL, /* cmp_lt */ + NULL, /* cmp_le */ + NULL, /* cmp_bitwise_and */ + NULL, /* cmp_contains */ + NULL, /* cmp_matches */ + + NULL, /* len */ + NULL, /* slice */ + }; + ftype_register(FT_PCRE, &pcre_type); +} + +#else /* No HAVE_LIBPCRE or GRegex */ void ftype_register_pcre(void) @@ -262,3 +397,17 @@ ftype_register_pcre(void) } #endif /* HAVE_LIBPCRE */ + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: t + * End: + * + * vi: set shiftwidth=4 tabstop=4 noexpandtab + * :indentSize=4:tabSize=4:noTabs=false: + */ + diff --git a/epan/ftypes/ftype-string.c b/epan/ftypes/ftype-string.c index 18754d7cc0..a3571bab23 100644 --- a/epan/ftypes/ftype-string.c +++ b/epan/ftypes/ftype-string.c @@ -28,8 +28,10 @@ #include <ftypes-int.h> #include <string.h> -#ifdef HAVE_LIBPCRE -#include <pcre.h> +#if defined(HAVE_LIBPCRE) || GLIB_CHECK_VERSION(2,14,0) +# ifdef HAVE_LIBPCRE +# include <pcre.h> +# endif #define CMP_MATCHES cmp_matches #else #define CMP_MATCHES NULL @@ -286,7 +288,34 @@ cmp_matches(fvalue_t *fv_a, fvalue_t *fv_b) } return FALSE; } -#endif +#elif GLIB_CHECK_VERSION(2,14,0) /* GRegex */ +static gboolean +cmp_matches(fvalue_t *fv_a, fvalue_t *fv_b) +{ + char *str = fv_a->value.string; + GRegex *regex = fv_b->value.re; + + /* fv_b is always a FT_PCRE, otherwise the dfilter semcheck() would have + * warned us. For the same reason (and because we're using g_malloc()), + * fv_b->value.re is not NULL. + */ + if (strcmp(fv_b->ftype->name, "FT_PCRE") != 0) { + return FALSE; + } + if (! regex) { + return FALSE; + } + return g_regex_match_full( + regex, /* Compiled PCRE */ + str, /* The data to check for the pattern... */ + (int)strlen(str), /* ... and its length */ + 0, /* Start offset within data */ + 0, /* GRegexMatchFlags */ + NULL, /* We are not interested in the match information */ + NULL /* We don't want error information */ + ); +} +#endif /* HAVE_LIBPCRE / GRegex */ void ftype_register_string(void) diff --git a/epan/ftypes/ftype-tvbuff.c b/epan/ftypes/ftype-tvbuff.c index 418961dd1e..dc0f6186b4 100644 --- a/epan/ftypes/ftype-tvbuff.c +++ b/epan/ftypes/ftype-tvbuff.c @@ -28,8 +28,10 @@ #include <ftypes-int.h> #include <string.h> -#ifdef HAVE_LIBPCRE -#include <pcre.h> +#if defined(HAVE_LIBPCRE) || GLIB_CHECK_VERSION(2,14,0) +# ifdef HAVE_LIBPCRE +# include <pcre.h> +# endif #define CMP_MATCHES cmp_matches #else #define CMP_MATCHES NULL @@ -80,8 +82,8 @@ val_from_string(fvalue_t *fv, char *s, LogFunc logfunc _U_) /* Make a tvbuff from the string. We can drop the * terminating NUL. */ - private_data = g_memdup(s, (guint)strlen(s)); - new_tvb = tvb_new_real_data(private_data, + private_data = g_memdup(s, (guint)strlen(s)); + new_tvb = tvb_new_real_data(private_data, (guint)strlen(s), (gint)strlen(s)); /* Let the tvbuff know how to delete the data. */ @@ -109,7 +111,7 @@ val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFu /* Make a tvbuff from the bytes */ private_data = g_memdup(fv_bytes->value.bytes->data, fv_bytes->value.bytes->len); - new_tvb = tvb_new_real_data(private_data, + new_tvb = tvb_new_real_data(private_data, fv_bytes->value.bytes->len, fv_bytes->value.bytes->len); @@ -356,8 +358,47 @@ cmp_matches(fvalue_t *fv_a, fvalue_t *fv_b) } return FALSE; } -#endif +#elif GLIB_CHECK_VERSION(2,14,0) /* GRegex */ +static gboolean +cmp_matches(fvalue_t *fv_a, fvalue_t *fv_b) +{ + tvbuff_t *tvb = fv_a->value.tvb; + GRegex *regex = fv_b->value.re; + volatile gboolean rc = FALSE; + const char *data = NULL; /* tvb data */ + guint32 tvb_len; /* tvb length */ + /* fv_b is always a FT_PCRE, otherwise the dfilter semcheck() would have + * warned us. For the same reason (and because we're using g_malloc()), + * fv_b->value.re is not NULL. + */ + if (strcmp(fv_b->ftype->name, "FT_PCRE") != 0) { + return FALSE; + } + if (! regex) { + return FALSE; + } + TRY { + tvb_len = tvb_length(tvb); + data = (const char *)tvb_get_ptr(tvb, 0, tvb_len); + rc = g_regex_match_full( + regex, /* Compiled PCRE */ + data, /* The data to check for the pattern... */ + tvb_len, /* ... and its length */ + 0, /* Start offset within data */ + G_REGEX_RAW, /* GRegexMatchFlags */ + NULL, /* We are not interested in the match information */ + NULL /* We don't want error information */ + ); + /* NOTE - DO NOT g_free(data) */ + } + CATCH_ALL { + return FALSE; + } + ENDTRY; + return rc; +} +#endif /* HAVE_LIBPCRE / GRegex */ void ftype_register_tvbuff(void) { diff --git a/epan/ftypes/ftypes-int.h b/epan/ftypes/ftypes-int.h index 0e8154e400..e84cd42d83 100644 --- a/epan/ftypes/ftypes-int.h +++ b/epan/ftypes/ftypes-int.h @@ -38,6 +38,8 @@ struct _pcre_tuple_t { pcre_extra *ex; char *error; }; +#elif GLIB_CHECK_VERSION(2,14,0) /* No HAVE_LIBPCRE. Try falling back to GRegex. */ + #endif /* HAVE_LIBPCRE */ void diff --git a/epan/ftypes/ftypes.h b/epan/ftypes/ftypes.h index 29744c83d2..5499912ec4 100644 --- a/epan/ftypes/ftypes.h +++ b/epan/ftypes/ftypes.h @@ -169,6 +169,8 @@ typedef struct _fvalue_t { tvbuff_t *tvb; #ifdef HAVE_LIBPCRE pcre_tuple_t *re; +#elif GLIB_CHECK_VERSION(2,14,0) /* Try falling back to GRegex. */ + GRegex *re; #endif /* HAVE_LIBPCRE */ } value; diff --git a/gtk/dfilter_expr_dlg.c b/gtk/dfilter_expr_dlg.c index 6b6c970e01..0969119909 100644 --- a/gtk/dfilter_expr_dlg.c +++ b/gtk/dfilter_expr_dlg.c @@ -249,7 +249,7 @@ show_relations(GtkWidget *relation_list, ftenum_t ftype) ftype_can_le(ftype) || (ftype_can_slice(ftype) && ftype_can_le(FT_BYTES))); add_relation_list(relation_list, "contains", ftype_can_contains(ftype) || (ftype_can_slice(ftype) && ftype_can_contains(FT_BYTES))); -#ifdef HAVE_LIBPCRE +#if defined(HAVE_LIBPCRE) || GLIB_CHECK_VERSION(2,14,0) add_relation_list(relation_list, "matches", ftype_can_matches(ftype) || (ftype_can_slice(ftype) && ftype_can_matches(FT_BYTES))); #endif @@ -938,7 +938,7 @@ dfilter_expr_dlg_new(GtkWidget *filter_te) GtkTreeSelection *l_sel; proto_initialize_all_prefixes(); - + window = dlg_conf_window_new("Wireshark: Filter Expression"); gtk_window_set_default_size(GTK_WINDOW(window), 500, 400); gtk_container_set_border_width(GTK_CONTAINER(window), 5); @@ -1124,7 +1124,7 @@ dfilter_expr_dlg_new(GtkWidget *filter_te) continue; } - g_snprintf(str, TAG_STRING_LEN, "%s - %s", + g_snprintf(str, TAG_STRING_LEN, "%s - %s", proto_get_protocol_short_name(protocol), proto_get_protocol_long_name(protocol)); strp=str; diff --git a/version_info.c b/version_info.c index 528b04b930..4850773029 100644 --- a/version_info.c +++ b/version_info.c @@ -186,7 +186,7 @@ get_compiled_version_info(GString *str, void (*additional_info)(GString *)) (*additional_info)(str); g_string_append(str, "."); -#ifndef HAVE_LIBPCRE +#if !defined(HAVE_LIBPCRE) && !GLIB_CHECK_VERSION(2,14,0) g_string_append(str, "\nNOTE: this build doesn't support the \"matches\" operator for Wireshark filter syntax"); g_string_append(str, "."); |