aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.in1
-rw-r--r--epan/dfilter/semcheck.c14
-rw-r--r--epan/ftypes/ftype-bytes.c36
-rw-r--r--epan/ftypes/ftype-pcre.c151
-rw-r--r--epan/ftypes/ftype-string.c35
-rw-r--r--epan/ftypes/ftype-tvbuff.c53
-rw-r--r--epan/ftypes/ftypes-int.h2
-rw-r--r--epan/ftypes/ftypes.h2
-rw-r--r--gtk/dfilter_expr_dlg.c6
-rw-r--r--version_info.c2
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 */
+ &regex_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, ".");