aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
Diffstat (limited to 'epan')
-rw-r--r--epan/column.c2
-rw-r--r--epan/dfilter/dfilter-int.h11
-rw-r--r--epan/dfilter/dfilter-macro.c47
-rw-r--r--epan/dfilter/dfilter.c63
-rw-r--r--epan/dfilter/dfilter.h20
-rw-r--r--epan/dfilter/dfunctions.c12
-rw-r--r--epan/dfilter/dfunctions.h2
-rw-r--r--epan/dfilter/grammar.lemon16
-rw-r--r--epan/dfilter/scanner.l34
-rw-r--r--epan/dfilter/semcheck.c268
-rw-r--r--epan/dfilter/sttype-function.h1
-rw-r--r--epan/dissectors/packet-ncp2222.inc8
-rw-r--r--epan/ftypes/ftype-bytes.c137
-rw-r--r--epan/ftypes/ftype-double.c16
-rw-r--r--epan/ftypes/ftype-guid.c5
-rw-r--r--epan/ftypes/ftype-integer.c135
-rw-r--r--epan/ftypes/ftype-ipv4.c15
-rw-r--r--epan/ftypes/ftype-ipv6.c13
-rw-r--r--epan/ftypes/ftype-pcre.c16
-rw-r--r--epan/ftypes/ftype-string.c6
-rw-r--r--epan/ftypes/ftype-time.c16
-rw-r--r--epan/ftypes/ftype-tvbuff.c6
-rw-r--r--epan/ftypes/ftypes-int.h4
-rw-r--r--epan/ftypes/ftypes.c26
-rw-r--r--epan/ftypes/ftypes.h6
-rw-r--r--epan/funnel.h2
-rw-r--r--epan/tap.c12
-rw-r--r--epan/wslua/wslua_field.c6
-rw-r--r--epan/wslua/wslua_gui.c7
29 files changed, 511 insertions, 401 deletions
diff --git a/epan/column.c b/epan/column.c
index c5aacd9777..503a2c120f 100644
--- a/epan/column.c
+++ b/epan/column.c
@@ -799,7 +799,7 @@ build_column_format_array(column_info *cinfo, const gint num_cols, const gboolea
if (cinfo->col_fmt[i] == COL_CUSTOM) {
cinfo->col_custom_field[i] = g_strdup(get_column_custom_field(i));
cinfo->col_custom_occurrence[i] = get_column_custom_occurrence(i);
- if(!dfilter_compile(cinfo->col_custom_field[i], &cinfo->col_custom_dfilter[i])) {
+ if(!dfilter_compile(cinfo->col_custom_field[i], &cinfo->col_custom_dfilter[i], NULL)) {
/* XXX: Should we issue a warning? */
g_free(cinfo->col_custom_field[i]);
cinfo->col_custom_field[i] = NULL;
diff --git a/epan/dfilter/dfilter-int.h b/epan/dfilter/dfilter-int.h
index 8a7511de05..40e55488b5 100644
--- a/epan/dfilter/dfilter-int.h
+++ b/epan/dfilter/dfilter-int.h
@@ -44,6 +44,7 @@ typedef struct {
/* Syntax Tree stuff */
stnode_t *st_root;
gboolean syntax_error;
+ gchar *error_message;
GPtrArray *insns;
GPtrArray *consts;
GHashTable *loaded_fields;
@@ -54,6 +55,12 @@ typedef struct {
int first_constant; /* first register used as a constant */
} dfwork_t;
+/*
+ * XXX - if we're using a version of Flex that supports reentrant lexical
+ * analyzers, we should put this into the lexical analyzer's state.
+ */
+extern dfwork_t *global_dfw;
+
/* Constructor/Destructor prototypes for Lemon Parser */
void *DfilterAlloc(void* (*)(gsize));
@@ -66,9 +73,9 @@ extern stnode_t *df_lval;
/* Return value for error in scanner. */
#define SCAN_FAILED -1 /* not 0, as that means end-of-input */
-/* Set dfilter_error_msg_buf and dfilter_error_msg */
+/* Set dfw->error_message */
void
-dfilter_fail(const char *format, ...) G_GNUC_PRINTF(1, 2);
+dfilter_fail(dfwork_t *dfw, const char *format, ...) G_GNUC_PRINTF(2, 3);
void
DfilterTrace(FILE *TraceFILE, char *zTracePrompt);
diff --git a/epan/dfilter/dfilter-macro.c b/epan/dfilter/dfilter-macro.c
index 578bac60c6..132c9fe5a0 100644
--- a/epan/dfilter/dfilter-macro.c
+++ b/epan/dfilter/dfilter-macro.c
@@ -30,7 +30,6 @@
#include "dfilter.h"
#include "dfilter-macro.h"
#include <ftypes/ftypes-int.h>
-#include <epan/emem.h>
#include <epan/uat-int.h>
#include <epan/proto.h>
#include <wsutil/file_util.h>
@@ -110,7 +109,8 @@ void dfilter_macro_save(const gchar* filename, gchar** error) {
FILE* f = ws_fopen(filename,"w");
if (!f) {
- *error = wmem_strdup_printf(NULL, "Could not open file: '%s', error: %s\n", filename, g_strerror(errno) );
+ if (error != NULL)
+ *error = g_strdup_printf("Could not open file: '%s', error: %s\n", filename, g_strerror(errno) );
return;
}
@@ -170,11 +170,13 @@ static gchar* dfilter_macro_resolve(gchar* name, gchar** args, gchar** error) {
if(e->usable) {
return wmem_strdup(NULL, e->repr);
} else {
- *error = wmem_strdup_printf(NULL, "macro '%s' is unusable", name);
+ if (error != NULL)
+ *error = g_strdup_printf("macro '%s' is unusable", name);
return NULL;
}
} else {
- *error = wmem_strdup_printf(NULL, "macro '%s' does not exist", name);
+ if (error != NULL)
+ *error = g_strdup_printf("macro '%s' does not exist", name);
return NULL;
}
}
@@ -186,8 +188,10 @@ static gchar* dfilter_macro_resolve(gchar* name, gchar** args, gchar** error) {
}
if (argc != m->argc) {
- *error = wmem_strdup_printf(NULL, "wrong number of arguments for macro '%s', expecting %d instead of %d",
- name, m->argc, argc);
+ if (error != NULL) {
+ *error = g_strdup_printf("wrong number of arguments for macro '%s', expecting %d instead of %d",
+ name, m->argc, argc);
+ }
return NULL;
}
@@ -223,7 +227,8 @@ static const gchar* dfilter_macro_apply_recurse(const gchar* text, guint depth,
gboolean changed = FALSE;
if ( depth > 31) {
- *error = wmem_strdup(NULL, "too much nesting in macros");
+ if (error != NULL)
+ *error = g_strdup("too much nesting in macros");
return NULL;
}
@@ -240,7 +245,8 @@ static const gchar* dfilter_macro_apply_recurse(const gchar* text, guint depth,
} \
} while(0)
- *error = NULL;
+ if (error != NULL)
+ *error = NULL;
out = g_string_sized_new(64);
while(1) {
@@ -295,7 +301,8 @@ static const gchar* dfilter_macro_apply_recurse(const gchar* text, guint depth,
g_ptr_array_add(args,NULL);
resolved = dfilter_macro_resolve(name->str, (gchar**)args->pdata, error);
- if (*error) goto on_error;
+ if (resolved == NULL)
+ goto on_error;
changed = TRUE;
@@ -306,17 +313,20 @@ static const gchar* dfilter_macro_apply_recurse(const gchar* text, guint depth,
state = OUTSIDE;
} else if ( c == '\0') {
- *error = wmem_strdup(NULL, "end of filter in the middle of a macro expression");
+ if (error != NULL)
+ *error = g_strdup("end of filter in the middle of a macro expression");
goto on_error;
} else {
- *error = wmem_strdup(NULL, "invalid char in macro name");
+ if (error != NULL)
+ *error = g_strdup("invalid character in macro name");
goto on_error;
}
break;
} case ARGS: {
switch(c) {
case '\0': {
- *error = wmem_strdup(NULL, "end of filter in the middle of a macro expression");
+ if (error != NULL)
+ *error = g_strdup("end of filter in the middle of a macro expression");
goto on_error;
} case ';': {
g_ptr_array_add(args,g_string_free(arg,FALSE));
@@ -329,7 +339,8 @@ static const gchar* dfilter_macro_apply_recurse(const gchar* text, guint depth,
g_string_append_c(arg,c);
break;
} else {
- *error = wmem_strdup(NULL, "end of filter in the middle of a macro expression");
+ if (error != NULL)
+ *error = g_strdup("end of filter in the middle of a macro expression");
goto on_error;
}
} default: {
@@ -343,7 +354,8 @@ static const gchar* dfilter_macro_apply_recurse(const gchar* text, guint depth,
arg = NULL;
resolved = dfilter_macro_resolve(name->str, (gchar**)args->pdata, error);
- if (*error) goto on_error;
+ if (resolved == NULL)
+ goto on_error;
changed = TRUE;
@@ -368,7 +380,7 @@ finish:
if (changed) {
const gchar* resolved = dfilter_macro_apply_recurse(out->str, depth + 1, error);
g_string_free(out,TRUE);
- return (*error) ? NULL : resolved;
+ return resolved;
} else {
const gchar* out_str = wmem_strdup(NULL, out->str);
g_string_free(out,TRUE);
@@ -378,7 +390,10 @@ finish:
on_error:
{
FREE_ALL();
- if (! *error) *error = wmem_strdup(NULL, "unknown error in macro expression");
+ if (error != NULL) {
+ if (*error == NULL)
+ *error = g_strdup("unknown error in macro expression");
+ }
g_string_free(out,TRUE);
return NULL;
}
diff --git a/epan/dfilter/dfilter.c b/epan/dfilter/dfilter.c
index 8e21d30853..903ec33868 100644
--- a/epan/dfilter/dfilter.c
+++ b/epan/dfilter/dfilter.c
@@ -34,10 +34,6 @@
#define DFILTER_TOKEN_ID_OFFSET 1
-/* Global error message space for dfilter_compile errors */
-static gchar dfilter_error_msg_buf[1024];
-const gchar *dfilter_error_msg; /* NULL when no error resulted */
-
/* From scanner.c */
void df_scanner_text(const char *text);
void df_scanner_cleanup(void);
@@ -46,24 +42,26 @@ int df_lex(void);
/* Holds the singular instance of our Lemon parser object */
static void* ParserObj = NULL;
+/*
+ * XXX - if we're using a version of Flex that supports reentrant lexical
+ * analyzers, we should put this into the lexical analyzer's state.
+ */
+dfwork_t *global_dfw;
+
void
-dfilter_fail(const char *format, ...)
+dfilter_fail(dfwork_t *dfw, const char *format, ...)
{
va_list args;
/* If we've already reported one error, don't overwite it */
- if (dfilter_error_msg != NULL)
+ if (dfw->error_message != NULL)
return;
va_start(args, format);
-
- g_vsnprintf(dfilter_error_msg_buf, sizeof(dfilter_error_msg_buf),
- format, args);
- dfilter_error_msg = dfilter_error_msg_buf;
+ dfw->error_message = g_strdup_vprintf(format, args);
va_end(args);
}
-
/* Initialize the dfilter module */
void
dfilter_init(void)
@@ -110,7 +108,7 @@ dfilter_new(void)
df = g_new0(dfilter_t, 1);
df->insns = NULL;
- df->deprecated = NULL;
+ df->deprecated = NULL;
return df;
}
@@ -202,11 +200,15 @@ dfwork_free(dfwork_t *dfw)
free_insns(dfw->consts);
}
+ /*
+ * We don't free the error message string; our caller will return
+ * it to its caller.
+ */
g_free(dfw);
}
gboolean
-dfilter_compile(const gchar *text, dfilter_t **dfp)
+dfilter_compile(const gchar *text, dfilter_t **dfp, gchar **err_msg)
{
int token;
dfilter_t *dfilter;
@@ -216,26 +218,28 @@ dfilter_compile(const gchar *text, dfilter_t **dfp)
guint i;
/* XXX, GHashTable */
GPtrArray *deprecated;
- gchar *temp_error_msg;
g_assert(dfp);
if (!text) {
*dfp = NULL;
+ if (err_msg != NULL)
+ *err_msg = g_strdup("BUG: NULL text pointer passed to dfilter_compile()");
return FALSE;
}
- dfilter_error_msg = NULL;
-
- if ( !( text = dfilter_macro_apply(text, &temp_error_msg) ) ) {
- /* Move the ep_ allocation up a layer */
- dfilter_error_msg = ep_strdup(temp_error_msg);
- wmem_free(NULL, temp_error_msg);
+ if ( !( text = dfilter_macro_apply(text, err_msg) ) ) {
return FALSE;
}
dfw = dfwork_new();
+ /*
+ * XXX - if we're using a version of Flex that supports reentrant lexical
+ * analyzers, we should put this into the lexical analyzer's state.
+ */
+ global_dfw = dfw;
+
df_scanner_text(text);
deprecated = g_ptr_array_new();
@@ -353,12 +357,18 @@ dfilter_compile(const gchar *text, dfilter_t **dfp)
*dfp = dfilter;
}
/* SUCCESS */
+ global_dfw = NULL;
dfwork_free(dfw);
wmem_free(NULL, (char*)text);
return TRUE;
FAILURE:
if (dfw) {
+ if (err_msg != NULL)
+ *err_msg = dfw->error_message;
+ else
+ g_free(dfw->error_message);
+ global_dfw = NULL;
dfwork_free(dfw);
}
for (i = 0; i < deprecated->len; ++i) {
@@ -366,11 +376,18 @@ FAILURE:
g_free(depr);
}
g_ptr_array_free(deprecated, TRUE);
- dfilter_fail("Unable to parse filter string \"%s\".", text);
- wmem_free(NULL, (char*)text);
+ if (err_msg != NULL) {
+ /*
+ * Default error message.
+ *
+ * XXX - we should really make sure that this is never the
+ * case for any error.
+ */
+ if (*err_msg == NULL)
+ *err_msg = g_strdup_printf("Unable to parse filter string \"%s\".", text);
+ }
*dfp = NULL;
return FALSE;
-
}
diff --git a/epan/dfilter/dfilter.h b/epan/dfilter/dfilter.h
index b408dc7757..1bbf907ec4 100644
--- a/epan/dfilter/dfilter.h
+++ b/epan/dfilter/dfilter.h
@@ -50,17 +50,16 @@ dfilter_cleanup(void);
* a pointer to the newly-allocated dfilter_t
* structure.
*
- * On failure, dfilter_error_msg points to an
- * appropriate error message. This error message is
- * a global string, so another invocation of
- * dfilter_compile() will clear it. The dfilter*
- * will be set to NULL after a failure.
+ * On failure, *err_msg is set to point to the error
+ * message. This error message is allocated with
+ * g_malloc(), and must be freed with g_free().
+ * The dfilter* will be set to NULL after a failure.
*
* Returns TRUE on success, FALSE on failure.
*/
WS_DLL_PUBLIC
gboolean
-dfilter_compile(const gchar *text, dfilter_t **dfp);
+dfilter_compile(const gchar *text, dfilter_t **dfp, gchar **err_msg);
/* Frees all memory used by dfilter, and frees
* the dfilter itself. */
@@ -68,15 +67,6 @@ WS_DLL_PUBLIC
void
dfilter_free(dfilter_t *df);
-
-/* dfilter_error_msg is NULL if there was no error during dfilter_compile,
- * otherwise it points to a displayable error message. With MSVC and a
- * libwireshark.dll, we need a special declaration.
- */
-
-WS_DLL_PUBLIC const gchar *dfilter_error_msg;
-
-
/* Apply compiled dfilter */
WS_DLL_PUBLIC
gboolean
diff --git a/epan/dfilter/dfunctions.c b/epan/dfilter/dfunctions.c
index 6394a1e482..204e6f712b 100644
--- a/epan/dfilter/dfunctions.c
+++ b/epan/dfilter/dfunctions.c
@@ -22,8 +22,8 @@
#include <glib.h>
-#include "dfunctions.h"
#include "dfilter-int.h"
+#include "dfunctions.h"
#include <string.h>
@@ -142,7 +142,7 @@ df_func_count(GList* arg1list, GList *arg2junk _U_, GList **retval)
/* For upper(), lower() and len(), checks that the parameter passed to
* it is an FT_STRING */
static void
-ul_semcheck_params(int param_num, stnode_t *st_node)
+ul_semcheck_params(dfwork_t *dfw, int param_num, stnode_t *st_node)
{
sttype_id_t type;
ftenum_t ftype;
@@ -156,12 +156,12 @@ ul_semcheck_params(int param_num, stnode_t *st_node)
hfinfo = (header_field_info *)stnode_data(st_node);
ftype = hfinfo->type;
if (!IS_FT_STRING(ftype)) {
- dfilter_fail("Only strings can be used in upper() or lower() or len()");
+ dfilter_fail(dfw, "Only strings can be used in upper() or lower() or len()");
THROW(TypeError);
}
break;
default:
- dfilter_fail("Only string-type fields can be used in upper() or lower() or len()");
+ dfilter_fail(dfw, "Only string-type fields can be used in upper() or lower() or len()");
THROW(TypeError);
}
}
@@ -171,7 +171,7 @@ ul_semcheck_params(int param_num, stnode_t *st_node)
}
static void
-ul_semcheck_field_param(int param_num, stnode_t *st_node)
+ul_semcheck_field_param(dfwork_t *dfw, int param_num, stnode_t *st_node)
{
sttype_id_t type;
@@ -182,7 +182,7 @@ ul_semcheck_field_param(int param_num, stnode_t *st_node)
case STTYPE_FIELD:
break;
default:
- dfilter_fail("Only type fields can be used as parameter "
+ dfilter_fail(dfw, "Only type fields can be used as parameter "
"for size() or count()");
THROW(TypeError);
}
diff --git a/epan/dfilter/dfunctions.h b/epan/dfilter/dfunctions.h
index 2b7957ec2c..96aed53bc6 100644
--- a/epan/dfilter/dfunctions.h
+++ b/epan/dfilter/dfunctions.h
@@ -29,7 +29,7 @@
typedef gboolean (*DFFuncType)(GList *arg1list, GList *arg2list, GList **retval);
/* The semantic check for the dfilter function */
-typedef void (*DFSemCheckType)(int param_num, stnode_t *st_node);
+typedef void (*DFSemCheckType)(dfwork_t *dfw, int param_num, stnode_t *st_node);
/* If a function needs more args than this, increase
* this macro and add more arg members to the dfvm_insn_t
diff --git a/epan/dfilter/grammar.lemon b/epan/dfilter/grammar.lemon
index c52fe7ad40..abd6e9a1cd 100644
--- a/epan/dfilter/grammar.lemon
+++ b/epan/dfilter/grammar.lemon
@@ -68,35 +68,35 @@ any "error" symbols are shifted, if possible. */
header_field_info *hfinfo;
if (!TOKEN) {
- dfilter_fail("Unexpected end of filter string.");
+ dfilter_fail(dfw, "Unexpected end of filter string.");
return;
}
switch(stnode_type_id(TOKEN)) {
case STTYPE_UNINITIALIZED:
- dfilter_fail("Syntax error.");
+ dfilter_fail(dfw, "Syntax error.");
break;
case STTYPE_TEST:
- dfilter_fail("Syntax error, TEST.");
+ dfilter_fail(dfw, "Syntax error, TEST.");
break;
case STTYPE_STRING:
- dfilter_fail("The string \"%s\" was unexpected in this context.",
+ dfilter_fail(dfw, "The string \"%s\" was unexpected in this context.",
(char *)stnode_data(TOKEN));
break;
case STTYPE_UNPARSED:
- dfilter_fail("\"%s\" was unexpected in this context.",
+ dfilter_fail(dfw, "\"%s\" was unexpected in this context.",
(char *)stnode_data(TOKEN));
break;
case STTYPE_INTEGER:
- dfilter_fail("The integer %d was unexpected in this context.",
+ dfilter_fail(dfw, "The integer %d was unexpected in this context.",
stnode_value(TOKEN));
break;
case STTYPE_FIELD:
hfinfo = (header_field_info *)stnode_data(TOKEN);
- dfilter_fail("Syntax error near \"%s\".", hfinfo->abbrev);
+ dfilter_fail(dfw, "Syntax error near \"%s\".", hfinfo->abbrev);
break;
case STTYPE_FUNCTION:
- dfilter_fail("The function s was unexpected in this context.");
+ dfilter_fail(dfw, "The function s was unexpected in this context.");
break;
/* These aren't handed to use as terminal tokens from
diff --git a/epan/dfilter/scanner.l b/epan/dfilter/scanner.l
index f09f30b40c..d3b71a39f9 100644
--- a/epan/dfilter/scanner.l
+++ b/epan/dfilter/scanner.l
@@ -68,9 +68,9 @@
/*#undef YY_NO_UNPUT*/
static int set_lval(int token, gpointer data);
-static int set_lval_int(int token, char *s);
+static int set_lval_int(dfwork_t *dfw, int token, char *s);
static int simple(int token);
-static gboolean str_to_gint32(char *s, gint32* pint);
+static gboolean str_to_gint32(dfwork_t *dfw, char *s, gint32* pint);
GString* quoted_string = NULL;
static void mark_lval_deprecated(const char *s);
@@ -128,12 +128,12 @@ static void mark_lval_deprecated(const char *s);
<RANGE_INT>[+-]?[[:digit:]]+ {
BEGIN(RANGE_PUNCT);
- return set_lval_int(TOKEN_INTEGER, yytext);
+ return set_lval_int(global_dfw, TOKEN_INTEGER, yytext);
}
<RANGE_INT>[+-]?0x[[:xdigit:]]+ {
BEGIN(RANGE_PUNCT);
- return set_lval_int(TOKEN_INTEGER, yytext);
+ return set_lval_int(global_dfw, TOKEN_INTEGER, yytext);
}
<RANGE_INT,RANGE_PUNCT>":" {
@@ -159,7 +159,7 @@ static void mark_lval_deprecated(const char *s);
/* Error if none of the above while scanning a range (slice) */
<RANGE_PUNCT>[^:\-,\]]+ {
- dfilter_fail("Invalid string \"%s\" found while scanning slice.", yytext);
+ dfilter_fail(global_dfw, "Invalid string \"%s\" found while scanning slice.", yytext);
return SCAN_FAILED;
}
@@ -168,7 +168,7 @@ static void mark_lval_deprecated(const char *s);
*/
<RANGE_INT>. {
- dfilter_fail("Invalid character \"%s\" found while scanning slice; expected integer.", yytext);
+ dfilter_fail(global_dfw, "Invalid character \"%s\" found while scanning slice; expected integer.", yytext);
return SCAN_FAILED;
}
@@ -200,7 +200,7 @@ static void mark_lval_deprecated(const char *s);
See:
http://www.gnu.org/software/flex/manual/html_node/flex_13.html */
- dfilter_fail("The final quote was missing from a quoted string.");
+ dfilter_fail(global_dfw, "The final quote was missing from a quoted string.");
return SCAN_FAILED;
}
@@ -221,7 +221,7 @@ static void mark_lval_deprecated(const char *s);
if (result > 0xff) {
g_string_free(quoted_string, TRUE);
quoted_string = NULL;
- dfilter_fail("%s is larger than 255.", yytext);
+ dfilter_fail(global_dfw, "%s is larger than 255.", yytext);
return SCAN_FAILED;
}
g_string_append_c(quoted_string, (gchar) result);
@@ -340,12 +340,12 @@ set_lval(int token, gpointer data)
}
static int
-set_lval_int(int token, char *s)
+set_lval_int(dfwork_t *dfw, int token, char *s)
{
sttype_id_t type_id = STTYPE_UNINITIALIZED;
gint32 val;
- if (!str_to_gint32(s, &val)) {
+ if (!str_to_gint32(dfw, s, &val)) {
return SCAN_FAILED;
}
@@ -363,7 +363,7 @@ set_lval_int(int token, char *s)
static gboolean
-str_to_gint32(char *s, gint32* pint)
+str_to_gint32(dfwork_t *dfw, char *s, gint32* pint)
{
char *endptr;
long integer;
@@ -373,22 +373,22 @@ str_to_gint32(char *s, gint32* pint)
if (errno == EINVAL || endptr == s || *endptr != '\0') {
/* This isn't a valid number. */
- dfilter_fail("\"%s\" is not a valid number.", s);
+ dfilter_fail(dfw, "\"%s\" is not a valid number.", s);
return FALSE;
}
if (errno == ERANGE) {
if (integer == LONG_MAX) {
- dfilter_fail("\"%s\" causes an integer overflow.", s);
+ dfilter_fail(dfw, "\"%s\" causes an integer overflow.", s);
}
else if (integer == LONG_MIN) {
- dfilter_fail("\"%s\" causes an integer underflow.", s);
+ dfilter_fail(dfw, "\"%s\" causes an integer underflow.", s);
}
else {
/*
* XXX - can "strtol()" set errno to ERANGE without
* returning LONG_MAX or LONG_MIN?
*/
- dfilter_fail("\"%s\" is not an integer.", s);
+ dfilter_fail(dfw, "\"%s\" is not an integer.", s);
}
return FALSE;
}
@@ -397,7 +397,7 @@ str_to_gint32(char *s, gint32* pint)
* Fits in a long, but not in a gint32 (a long might be
* 64 bits).
*/
- dfilter_fail("\"%s\" causes an integer overflow.", s);
+ dfilter_fail(dfw, "\"%s\" causes an integer overflow.", s);
return FALSE;
}
if (integer < G_MININT32) {
@@ -405,7 +405,7 @@ str_to_gint32(char *s, gint32* pint)
* Fits in a long, but not in a gint32 (a long might be
* 64 bits).
*/
- dfilter_fail("\"%s\" causes an integer underflow.", s);
+ dfilter_fail(dfw, "\"%s\" causes an integer underflow.", s);
return FALSE;
}
diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c
index bda8f49c4b..cc1a5df4bb 100644
--- a/epan/dfilter/semcheck.c
+++ b/epan/dfilter/semcheck.c
@@ -48,10 +48,10 @@
#endif
static void
-semcheck(stnode_t *st_node, GPtrArray *deprecated);
+semcheck(dfwork_t *dfw, stnode_t *st_node, GPtrArray *deprecated);
static stnode_t*
-check_param_entity(stnode_t *st_node);
+check_param_entity(dfwork_t *dfw, stnode_t *st_node);
typedef gboolean (*FtypeCanFunc)(enum ftenum);
@@ -137,6 +137,25 @@ compatible_ftypes(ftenum_t a, ftenum_t b)
return FALSE;
}
+/* Gets an fvalue from a string, and sets the error message on failure. */
+static fvalue_t*
+dfilter_fvalue_from_unparsed(dfwork_t *dfw, ftenum_t ftype, const char *s, gboolean allow_partial_value)
+{
+ /*
+ * Don't set the error message if it's already set.
+ */
+ return fvalue_from_unparsed(ftype, s, allow_partial_value,
+ dfw->error_message == NULL ? &dfw->error_message : NULL);
+}
+
+/* Gets an fvalue from a string, and sets the error message on failure. */
+static fvalue_t*
+dfilter_fvalue_from_string(dfwork_t *dfw, ftenum_t ftype, const char *s)
+{
+ return fvalue_from_string(ftype, s,
+ dfw->error_message == NULL ? &dfw->error_message : NULL);
+}
+
/* Creates a FT_UINT32 fvalue with a given value. */
static fvalue_t*
mk_uint32_fvalue(guint32 val)
@@ -165,7 +184,7 @@ mk_uint64_fvalue(guint64 val)
* This works only for ftypes that are integers. Returns the created fvalue_t*
* or NULL if impossible. */
static fvalue_t*
-mk_fvalue_from_val_string(header_field_info *hfinfo, char *s)
+mk_fvalue_from_val_string(dfwork_t *dfw, header_field_info *hfinfo, char *s)
{
static const true_false_string default_tf = { "True", "False" };
const true_false_string *tf = &default_tf;
@@ -230,8 +249,13 @@ mk_fvalue_from_val_string(header_field_info *hfinfo, char *s)
return mk_uint32_fvalue(FALSE);
}
else {
- dfilter_error_msg = NULL; /* Prefer this error message */
- dfilter_fail("\"%s\" cannot be found among the possible values for %s.",
+ /*
+ * Prefer this error message to whatever error message
+ * has already been set.
+ */
+ g_free(dfw->error_message);
+ dfw->error_message = NULL;
+ dfilter_fail(dfw, "\"%s\" cannot be found among the possible values for %s.",
s, hfinfo->abbrev);
return NULL;
}
@@ -239,18 +263,19 @@ mk_fvalue_from_val_string(header_field_info *hfinfo, char *s)
/* Do val_strings exist? */
if (!hfinfo->strings) {
- dfilter_fail("%s cannot accept strings as values.",
+ dfilter_fail(dfw, "%s cannot accept strings as values.",
hfinfo->abbrev);
return NULL;
}
- /* Reset the dfilter error message, since *something* interesting
- * will happen, and the error message will be more interesting than
- * any error message I happen to have now. */
- dfilter_error_msg = NULL;
+ /* Reset the error message, since *something* interesting will happen,
+ * and the error message will be more interesting than any error message
+ * I happen to have now. */
+ g_free(dfw->error_message);
+ dfw->error_message = NULL;
if (hfinfo->display & BASE_RANGE_STRING) {
- dfilter_fail("\"%s\" cannot accept [range] strings as values.",
+ dfilter_fail(dfw, "\"%s\" cannot accept [range] strings as values.",
hfinfo->abbrev);
}
else if (hfinfo->display & BASE_VAL64_STRING) {
@@ -262,7 +287,7 @@ mk_fvalue_from_val_string(header_field_info *hfinfo, char *s)
}
vals++;
}
- dfilter_fail("\"%s\" cannot be found among the possible values for %s.",
+ dfilter_fail(dfw, "\"%s\" cannot be found among the possible values for %s.",
s, hfinfo->abbrev);
}
else if (hfinfo->display == BASE_CUSTOM) {
@@ -272,7 +297,7 @@ mk_fvalue_from_val_string(header_field_info *hfinfo, char *s)
* integer, we have the string they're trying to match.
* -><-
*/
- dfilter_fail("\"%s\" cannot accept [custom] strings as values.",
+ dfilter_fail(dfw, "\"%s\" cannot accept [custom] strings as values.",
hfinfo->abbrev);
}
else {
@@ -286,7 +311,7 @@ mk_fvalue_from_val_string(header_field_info *hfinfo, char *s)
}
vals++;
}
- dfilter_fail("\"%s\" cannot be found among the possible values for %s.",
+ dfilter_fail(dfw, "\"%s\" cannot be found among the possible values for %s.",
s, hfinfo->abbrev);
}
return NULL;
@@ -347,7 +372,7 @@ is_bytes_type(enum ftenum type)
/* Check the semantics of an existence test. */
static void
-check_exists(stnode_t *st_arg1)
+check_exists(dfwork_t *dfw, stnode_t *st_arg1)
{
#ifdef DEBUG_dfilter
static guint i = 0;
@@ -360,7 +385,7 @@ check_exists(stnode_t *st_arg1)
break;
case STTYPE_STRING:
case STTYPE_UNPARSED:
- dfilter_fail("\"%s\" is neither a field nor a protocol name.",
+ dfilter_fail(dfw, "\"%s\" is neither a field nor a protocol name.",
(char *)stnode_data(st_arg1));
THROW(TypeError);
break;
@@ -372,14 +397,14 @@ check_exists(stnode_t *st_arg1)
* has at least 2 bytes starting at an offset of
* 3"?
*/
- dfilter_fail("You cannot test whether a range is present.");
+ dfilter_fail(dfw, "You cannot test whether a range is present.");
THROW(TypeError);
break;
case STTYPE_FUNCTION:
/* XXX - Maybe we should change functions so they can return fields,
* in which case the 'exist' should be fine. */
- dfilter_fail("You cannot test whether a function is present.");
+ dfilter_fail(dfw, "You cannot test whether a function is present.");
THROW(TypeError);
break;
@@ -393,6 +418,7 @@ check_exists(stnode_t *st_arg1)
}
struct check_drange_sanity_args {
+ dfwork_t *dfw;
stnode_t *st;
gboolean err;
};
@@ -428,13 +454,13 @@ check_drange_node_sanity(gpointer data, gpointer user_data)
if (entity && stnode_type_id(entity) == STTYPE_FIELD) {
hfinfo = (header_field_info *)stnode_data(entity);
- dfilter_fail("Range %d:%d specified for \"%s\" isn't valid, "
+ dfilter_fail(args->dfw, "Range %d:%d specified for \"%s\" isn't valid, "
"as length %d isn't positive",
start_offset, length,
hfinfo->abbrev,
length);
} else
- dfilter_fail("Range %d:%d isn't valid, "
+ dfilter_fail(args->dfw, "Range %d:%d isn't valid, "
"as length %d isn't positive",
start_offset, length,
length);
@@ -462,14 +488,14 @@ check_drange_node_sanity(gpointer data, gpointer user_data)
if (entity && stnode_type_id(entity) == STTYPE_FIELD) {
hfinfo = (header_field_info *)stnode_data(entity);
- dfilter_fail("Range %d-%d specified for \"%s\" isn't valid, "
+ dfilter_fail(args->dfw, "Range %d-%d specified for \"%s\" isn't valid, "
"as %d is greater than %d",
start_offset, end_offset,
hfinfo->abbrev,
start_offset, end_offset);
} else
- dfilter_fail("Range %d-%d isn't valid, "
+ dfilter_fail(args->dfw, "Range %d-%d isn't valid, "
"as %d is greater than %d",
start_offset, end_offset,
start_offset, end_offset);
@@ -487,10 +513,11 @@ check_drange_node_sanity(gpointer data, gpointer user_data)
}
static void
-check_drange_sanity(stnode_t *st)
+check_drange_sanity(dfwork_t *dfw, stnode_t *st)
{
struct check_drange_sanity_args args;
+ args.dfw = dfw;
args.st = st;
args.err = FALSE;
@@ -520,7 +547,7 @@ convert_to_bytes(stnode_t *arg)
}
static void
-check_function(stnode_t *st_node)
+check_function(dfwork_t *dfw, stnode_t *st_node)
{
df_func_def_t *funcdef;
GSList *params;
@@ -532,19 +559,19 @@ check_function(stnode_t *st_node)
nparams = g_slist_length(params);
if (nparams < funcdef->min_nargs) {
- dfilter_fail("Function %s needs at least %u arguments.",
+ dfilter_fail(dfw, "Function %s needs at least %u arguments.",
funcdef->name, funcdef->min_nargs);
THROW(TypeError);
} else if (nparams > funcdef->max_nargs) {
- dfilter_fail("Function %s can only accept %u arguments.",
+ dfilter_fail(dfw, "Function %s can only accept %u arguments.",
funcdef->name, funcdef->max_nargs);
THROW(TypeError);
}
iparam = 0;
while (params) {
- params->data = check_param_entity((stnode_t *)params->data);
- funcdef->semcheck_param_function(iparam, (stnode_t *)params->data);
+ params->data = check_param_entity(dfw, (stnode_t *)params->data);
+ funcdef->semcheck_param_function(dfw, iparam, (stnode_t *)params->data);
params = params->next;
iparam++;
}
@@ -553,8 +580,8 @@ check_function(stnode_t *st_node)
/* If the LHS of a relation test is a FIELD, run some checks
* and possibly some modifications of syntax tree nodes. */
static void
-check_relation_LHS_FIELD(const char *relation_string, FtypeCanFunc can_func,
- gboolean allow_partial_value,
+check_relation_LHS_FIELD(dfwork_t *dfw, const char *relation_string,
+ FtypeCanFunc can_func, gboolean allow_partial_value,
stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
{
stnode_t *new_st;
@@ -573,7 +600,7 @@ check_relation_LHS_FIELD(const char *relation_string, FtypeCanFunc can_func,
DebugLog((" 5 check_relation_LHS_FIELD(%s)\n", relation_string));
if (!can_func(ftype1)) {
- dfilter_fail("%s (type=%s) cannot participate in '%s' comparison.",
+ dfilter_fail(dfw, "%s (type=%s) cannot participate in '%s' comparison.",
hfinfo1->abbrev, ftype_pretty_name(ftype1),
relation_string);
THROW(TypeError);
@@ -584,14 +611,14 @@ check_relation_LHS_FIELD(const char *relation_string, FtypeCanFunc can_func,
ftype2 = hfinfo2->type;
if (!compatible_ftypes(ftype1, ftype2)) {
- dfilter_fail("%s and %s are not of compatible types.",
+ dfilter_fail(dfw, "%s and %s are not of compatible types.",
hfinfo1->abbrev, hfinfo2->abbrev);
THROW(TypeError);
}
/* Do this check even though you'd think that if
* they're compatible, then can_func() would pass. */
if (!can_func(ftype2)) {
- dfilter_fail("%s (type=%s) cannot participate in specified comparison.",
+ dfilter_fail(dfw, "%s (type=%s) cannot participate in specified comparison.",
hfinfo2->abbrev, ftype_pretty_name(ftype2));
THROW(TypeError);
}
@@ -601,9 +628,9 @@ check_relation_LHS_FIELD(const char *relation_string, FtypeCanFunc can_func,
if (strcmp(relation_string, "matches") == 0) {
/* Convert to a FT_PCRE */
if (type2 == STTYPE_STRING)
- fvalue = fvalue_from_string(FT_PCRE, s, dfilter_fail);
+ fvalue = dfilter_fvalue_from_string(dfw, FT_PCRE, s);
else
- fvalue = fvalue_from_unparsed(FT_PCRE, s, FALSE, dfilter_fail);
+ fvalue = dfilter_fvalue_from_unparsed(dfw, FT_PCRE, s, FALSE);
} else {
/* Skip incompatible fields */
while (hfinfo1->same_name_prev_id != -1 &&
@@ -614,13 +641,13 @@ check_relation_LHS_FIELD(const char *relation_string, FtypeCanFunc can_func,
}
if (type2 == STTYPE_STRING)
- fvalue = fvalue_from_string(ftype1, s, dfilter_fail);
+ fvalue = dfilter_fvalue_from_string(dfw, ftype1, s);
else
- fvalue = fvalue_from_unparsed(ftype1, s, allow_partial_value, dfilter_fail);
+ fvalue = dfilter_fvalue_from_unparsed(dfw, ftype1, s, allow_partial_value);
if (!fvalue) {
/* check value_string */
- fvalue = mk_fvalue_from_val_string(hfinfo1, s);
+ fvalue = mk_fvalue_from_val_string(dfw, hfinfo1, s);
}
}
@@ -633,10 +660,10 @@ check_relation_LHS_FIELD(const char *relation_string, FtypeCanFunc can_func,
stnode_free(st_arg2);
}
else if (type2 == STTYPE_RANGE) {
- check_drange_sanity(st_arg2);
+ check_drange_sanity(dfw, st_arg2);
if (!is_bytes_type(ftype1)) {
if (!ftype_can_slice(ftype1)) {
- dfilter_fail("\"%s\" is a %s and cannot be converted into a sequence of bytes.",
+ dfilter_fail(dfw, "\"%s\" is a %s and cannot be converted into a sequence of bytes.",
hfinfo1->abbrev,
ftype_pretty_name(ftype1));
THROW(TypeError);
@@ -653,19 +680,19 @@ check_relation_LHS_FIELD(const char *relation_string, FtypeCanFunc can_func,
ftype2 = funcdef->retval_ftype;
if (!compatible_ftypes(ftype1, ftype2)) {
- dfilter_fail("%s (type=%s) and return value of %s() (type=%s) are not of compatible types.",
+ dfilter_fail(dfw, "%s (type=%s) and return value of %s() (type=%s) are not of compatible types.",
hfinfo1->abbrev, ftype_pretty_name(ftype1),
funcdef->name, ftype_pretty_name(ftype2));
THROW(TypeError);
}
if (!can_func(ftype2)) {
- dfilter_fail("return value of %s() (type=%s) cannot participate in specified comparison.",
+ dfilter_fail(dfw, "return value of %s() (type=%s) cannot participate in specified comparison.",
funcdef->name, ftype_pretty_name(ftype2));
THROW(TypeError);
}
- check_function(st_arg2);
+ check_function(dfw, st_arg2);
}
else {
g_assert_not_reached();
@@ -673,7 +700,7 @@ check_relation_LHS_FIELD(const char *relation_string, FtypeCanFunc can_func,
}
static void
-check_relation_LHS_STRING(const char* relation_string,
+check_relation_LHS_STRING(dfwork_t *dfw, const char* relation_string,
FtypeCanFunc can_func, gboolean allow_partial_value _U_,
stnode_t *st_node,
stnode_t *st_arg1, stnode_t *st_arg2)
@@ -695,17 +722,17 @@ check_relation_LHS_STRING(const char* relation_string,
ftype2 = hfinfo2->type;
if (!can_func(ftype2)) {
- dfilter_fail("%s (type=%s) cannot participate in '%s' comparison.",
+ dfilter_fail(dfw, "%s (type=%s) cannot participate in '%s' comparison.",
hfinfo2->abbrev, ftype_pretty_name(ftype2),
relation_string);
THROW(TypeError);
}
s = (char*)stnode_data(st_arg1);
- fvalue = fvalue_from_string(ftype2, s, dfilter_fail);
+ fvalue = dfilter_fvalue_from_string(dfw, ftype2, s);
if (!fvalue) {
/* check value_string */
- fvalue = mk_fvalue_from_val_string(hfinfo2, s);
+ fvalue = mk_fvalue_from_val_string(dfw, hfinfo2, s);
if (!fvalue) {
THROW(TypeError);
}
@@ -717,15 +744,15 @@ check_relation_LHS_STRING(const char* relation_string,
}
else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED) {
/* Well now that's silly... */
- dfilter_fail("Neither \"%s\" nor \"%s\" are field or protocol names.",
+ dfilter_fail(dfw, "Neither \"%s\" nor \"%s\" are field or protocol names.",
(char *)stnode_data(st_arg1),
(char *)stnode_data(st_arg2));
THROW(TypeError);
}
else if (type2 == STTYPE_RANGE) {
- check_drange_sanity(st_arg2);
+ check_drange_sanity(dfw, st_arg2);
s = (char*)stnode_data(st_arg1);
- fvalue = fvalue_from_string(FT_BYTES, s, dfilter_fail);
+ fvalue = dfilter_fvalue_from_string(dfw, FT_BYTES, s);
if (!fvalue) {
THROW(TypeError);
}
@@ -738,19 +765,19 @@ check_relation_LHS_STRING(const char* relation_string,
ftype2 = funcdef->retval_ftype;
if (!can_func(ftype2)) {
- dfilter_fail("Return value of function %s (type=%s) cannot participate in '%s' comparison.",
+ dfilter_fail(dfw, "Return value of function %s (type=%s) cannot participate in '%s' comparison.",
funcdef->name, ftype_pretty_name(ftype2),
relation_string);
THROW(TypeError);
}
s = (char*)stnode_data(st_arg1);
- fvalue = fvalue_from_string(ftype2, s, dfilter_fail);
+ fvalue = dfilter_fvalue_from_string(dfw, ftype2, s);
if (!fvalue) {
THROW(TypeError);
}
- check_function(st_arg2);
+ check_function(dfw, st_arg2);
new_st = stnode_new(STTYPE_FVALUE, fvalue);
sttype_test_set2_args(st_node, new_st, st_arg2);
@@ -762,7 +789,7 @@ check_relation_LHS_STRING(const char* relation_string,
}
static void
-check_relation_LHS_UNPARSED(const char* relation_string,
+check_relation_LHS_UNPARSED(dfwork_t *dfw, const char* relation_string,
FtypeCanFunc can_func, gboolean allow_partial_value,
stnode_t *st_node,
stnode_t *st_arg1, stnode_t *st_arg2)
@@ -784,17 +811,17 @@ check_relation_LHS_UNPARSED(const char* relation_string,
ftype2 = hfinfo2->type;
if (!can_func(ftype2)) {
- dfilter_fail("%s (type=%s) cannot participate in '%s' comparison.",
+ dfilter_fail(dfw, "%s (type=%s) cannot participate in '%s' comparison.",
hfinfo2->abbrev, ftype_pretty_name(ftype2),
relation_string);
THROW(TypeError);
}
s = (char*)stnode_data(st_arg1);
- fvalue = fvalue_from_unparsed(ftype2, s, allow_partial_value, dfilter_fail);
+ fvalue = dfilter_fvalue_from_unparsed(dfw, ftype2, s, allow_partial_value);
if (!fvalue) {
/* check value_string */
- fvalue = mk_fvalue_from_val_string(hfinfo2, s);
+ fvalue = mk_fvalue_from_val_string(dfw, hfinfo2, s);
if (!fvalue) {
THROW(TypeError);
}
@@ -806,15 +833,15 @@ check_relation_LHS_UNPARSED(const char* relation_string,
}
else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED) {
/* Well now that's silly... */
- dfilter_fail("Neither \"%s\" nor \"%s\" are field or protocol names.",
+ dfilter_fail(dfw, "Neither \"%s\" nor \"%s\" are field or protocol names.",
(char *)stnode_data(st_arg1),
(char *)stnode_data(st_arg2));
THROW(TypeError);
}
else if (type2 == STTYPE_RANGE) {
- check_drange_sanity(st_arg2);
+ check_drange_sanity(dfw, st_arg2);
s = (char*)stnode_data(st_arg1);
- fvalue = fvalue_from_unparsed(FT_BYTES, s, allow_partial_value, dfilter_fail);
+ fvalue = dfilter_fvalue_from_unparsed(dfw, FT_BYTES, s, allow_partial_value);
if (!fvalue) {
THROW(TypeError);
}
@@ -827,19 +854,19 @@ check_relation_LHS_UNPARSED(const char* relation_string,
ftype2 = funcdef->retval_ftype;
if (!can_func(ftype2)) {
- dfilter_fail("return value of function %s() (type=%s) cannot participate in '%s' comparison.",
+ dfilter_fail(dfw, "return value of function %s() (type=%s) cannot participate in '%s' comparison.",
funcdef->name, ftype_pretty_name(ftype2), relation_string);
THROW(TypeError);
}
s = (char*)stnode_data(st_arg1);
- fvalue = fvalue_from_unparsed(ftype2, s, allow_partial_value, dfilter_fail);
+ fvalue = dfilter_fvalue_from_unparsed(dfw, ftype2, s, allow_partial_value);
if (!fvalue) {
THROW(TypeError);
}
- check_function(st_arg2);
+ check_function(dfw, st_arg2);
new_st = stnode_new(STTYPE_FVALUE, fvalue);
sttype_test_set2_args(st_node, new_st, st_arg2);
@@ -851,7 +878,8 @@ check_relation_LHS_UNPARSED(const char* relation_string,
}
static void
-check_relation_LHS_RANGE(const char *relation_string, FtypeCanFunc can_func _U_,
+check_relation_LHS_RANGE(dfwork_t *dfw, const char *relation_string,
+ FtypeCanFunc can_func _U_,
gboolean allow_partial_value,
stnode_t *st_node,
stnode_t *st_arg1, stnode_t *st_arg2)
@@ -874,7 +902,7 @@ check_relation_LHS_RANGE(const char *relation_string, FtypeCanFunc can_func _U_,
ftype1 = hfinfo1->type;
if (!ftype_can_slice(ftype1)) {
- dfilter_fail("\"%s\" is a %s and cannot be sliced into a sequence of bytes.",
+ dfilter_fail(dfw, "\"%s\" is a %s and cannot be sliced into a sequence of bytes.",
hfinfo1->abbrev, ftype_pretty_name(ftype1));
THROW(TypeError);
}
@@ -883,20 +911,20 @@ check_relation_LHS_RANGE(const char *relation_string, FtypeCanFunc can_func _U_,
ftype1 = funcdef->retval_ftype;
if (!ftype_can_slice(ftype1)) {
- dfilter_fail("Return value of function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
+ dfilter_fail(dfw, "Return value of function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
funcdef->name, ftype_pretty_name(ftype1));
THROW(TypeError);
}
- check_function(entity1);
+ check_function(dfw, entity1);
} else {
- dfilter_fail("Range is not supported, details: " G_STRLOC " entity: %p of type %d",
+ dfilter_fail(dfw, "Range is not supported, details: " G_STRLOC " entity: %p of type %d",
entity1, entity1 ? (int) stnode_type_id(entity1) : -1);
THROW(TypeError);
}
- check_drange_sanity(st_arg1);
+ check_drange_sanity(dfw, st_arg1);
if (type2 == STTYPE_FIELD) {
DebugLog((" 5 check_relation_LHS_RANGE(type2 = STTYPE_FIELD)\n"));
@@ -905,7 +933,7 @@ check_relation_LHS_RANGE(const char *relation_string, FtypeCanFunc can_func _U_,
if (!is_bytes_type(ftype2)) {
if (!ftype_can_slice(ftype2)) {
- dfilter_fail("\"%s\" is a %s and cannot be converted into a sequence of bytes.",
+ dfilter_fail(dfw, "\"%s\" is a %s and cannot be converted into a sequence of bytes.",
hfinfo2->abbrev,
ftype_pretty_name(ftype2));
THROW(TypeError);
@@ -922,9 +950,9 @@ check_relation_LHS_RANGE(const char *relation_string, FtypeCanFunc can_func _U_,
s = (char*)stnode_data(st_arg2);
if (strcmp(relation_string, "matches") == 0) {
/* Convert to a FT_PCRE */
- fvalue = fvalue_from_string(FT_PCRE, s, dfilter_fail);
+ fvalue = dfilter_fvalue_from_string(dfw, FT_PCRE, s);
} else {
- fvalue = fvalue_from_string(FT_BYTES, s, dfilter_fail);
+ fvalue = dfilter_fvalue_from_string(dfw, FT_BYTES, s);
}
if (!fvalue) {
DebugLog((" 5 check_relation_LHS_RANGE(type2 = STTYPE_STRING): Could not convert from string!\n"));
@@ -940,7 +968,7 @@ check_relation_LHS_RANGE(const char *relation_string, FtypeCanFunc can_func _U_,
len_range = drange_get_total_length(sttype_range_drange(st_arg1));
if (strcmp(relation_string, "matches") == 0) {
/* Convert to a FT_PCRE */
- fvalue = fvalue_from_unparsed(FT_PCRE, s, FALSE, dfilter_fail);
+ fvalue = dfilter_fvalue_from_unparsed(dfw, FT_PCRE, s, FALSE);
}
/* The RHS should be FT_BYTES. However, there is a special case where
@@ -952,17 +980,17 @@ check_relation_LHS_RANGE(const char *relation_string, FtypeCanFunc can_func _U_,
else if (len_range == 1 && strlen(s) == 4 && strncmp(s, "0x", 2) == 0) {
/* Even if the RHS string starts with "0x", it still could fail to
* be an integer. Try converting it here. */
- fvalue = fvalue_from_unparsed(FT_UINT8, s, allow_partial_value, dfilter_fail);
+ fvalue = dfilter_fvalue_from_unparsed(dfw, FT_UINT8, s, allow_partial_value);
if (fvalue) {
FVALUE_FREE(fvalue);
/* The value doees indeed fit into 8 bits. Create a BYTE_STRING
* from it. Since we know that the last 2 characters are a valid
* hex string, just use those directly. */
- fvalue = fvalue_from_unparsed(FT_BYTES, s+2, allow_partial_value, dfilter_fail);
+ fvalue = dfilter_fvalue_from_unparsed(dfw, FT_BYTES, s+2, allow_partial_value);
}
}
else {
- fvalue = fvalue_from_unparsed(FT_BYTES, s, allow_partial_value, dfilter_fail);
+ fvalue = dfilter_fvalue_from_unparsed(dfw, FT_BYTES, s, allow_partial_value);
}
if (!fvalue) {
DebugLog((" 5 check_relation_LHS_RANGE(type2 = STTYPE_UNPARSED): Could not convert from string!\n"));
@@ -974,7 +1002,7 @@ check_relation_LHS_RANGE(const char *relation_string, FtypeCanFunc can_func _U_,
}
else if (type2 == STTYPE_RANGE) {
DebugLog((" 5 check_relation_LHS_RANGE(type2 = STTYPE_RANGE)\n"));
- check_drange_sanity(st_arg2);
+ check_drange_sanity(dfw, st_arg2);
}
else if (type2 == STTYPE_FUNCTION) {
df_func_def_t *funcdef = sttype_function_funcdef(st_arg2);
@@ -982,7 +1010,7 @@ check_relation_LHS_RANGE(const char *relation_string, FtypeCanFunc can_func _U_,
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.",
+ dfilter_fail(dfw, "Return value of function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
funcdef->name,
ftype_pretty_name(ftype2));
THROW(TypeError);
@@ -994,7 +1022,7 @@ check_relation_LHS_RANGE(const char *relation_string, FtypeCanFunc can_func _U_,
sttype_test_set2_args(st_node, st_arg1, new_st);
}
- check_function(st_arg2);
+ check_function(dfw, st_arg2);
}
else {
g_assert_not_reached();
@@ -1002,7 +1030,7 @@ check_relation_LHS_RANGE(const char *relation_string, FtypeCanFunc can_func _U_,
}
static stnode_t*
-check_param_entity(stnode_t *st_node)
+check_param_entity(dfwork_t *dfw, stnode_t *st_node)
{
sttype_id_t e_type;
stnode_t *new_st;
@@ -1013,7 +1041,7 @@ check_param_entity(stnode_t *st_node)
/* If there's an unparsed string, change it to an FT_STRING */
if (e_type == STTYPE_UNPARSED) {
s = (char*)stnode_data(st_node);
- fvalue = fvalue_from_unparsed(FT_STRING, s, FALSE, dfilter_fail);
+ fvalue = dfilter_fvalue_from_unparsed(dfw, FT_STRING, s, FALSE);
if (!fvalue) {
THROW(TypeError);
}
@@ -1029,7 +1057,8 @@ check_param_entity(stnode_t *st_node)
/* If the LHS of a relation test is a FUNCTION, run some checks
* and possibly some modifications of syntax tree nodes. */
static void
-check_relation_LHS_FUNCTION(const char *relation_string, FtypeCanFunc can_func,
+check_relation_LHS_FUNCTION(dfwork_t *dfw, const char *relation_string,
+ FtypeCanFunc can_func,
gboolean allow_partial_value,
stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
{
@@ -1043,7 +1072,7 @@ check_relation_LHS_FUNCTION(const char *relation_string, FtypeCanFunc can_func,
df_func_def_t *funcdef2;
/* GSList *params; */
- check_function(st_arg1);
+ check_function(dfw, st_arg1);
type2 = stnode_type_id(st_arg2);
funcdef = sttype_function_funcdef(st_arg1);
@@ -1054,7 +1083,7 @@ check_relation_LHS_FUNCTION(const char *relation_string, FtypeCanFunc can_func,
DebugLog((" 5 check_relation_LHS_FUNCTION(%s)\n", relation_string));
if (!can_func(ftype1)) {
- dfilter_fail("Function %s (type=%s) cannot participate in '%s' comparison.",
+ dfilter_fail(dfw, "Function %s (type=%s) cannot participate in '%s' comparison.",
funcdef->name, ftype_pretty_name(ftype1),
relation_string);
THROW(TypeError);
@@ -1065,14 +1094,14 @@ check_relation_LHS_FUNCTION(const char *relation_string, FtypeCanFunc can_func,
ftype2 = hfinfo2->type;
if (!compatible_ftypes(ftype1, ftype2)) {
- dfilter_fail("Function %s and %s are not of compatible types.",
+ dfilter_fail(dfw, "Function %s and %s are not of compatible types.",
funcdef->name, hfinfo2->abbrev);
THROW(TypeError);
}
/* Do this check even though you'd think that if
* they're compatible, then can_func() would pass. */
if (!can_func(ftype2)) {
- dfilter_fail("%s (type=%s) cannot participate in specified comparison.",
+ dfilter_fail(dfw, "%s (type=%s) cannot participate in specified comparison.",
hfinfo2->abbrev, ftype_pretty_name(ftype2));
THROW(TypeError);
}
@@ -1081,9 +1110,9 @@ check_relation_LHS_FUNCTION(const char *relation_string, FtypeCanFunc can_func,
s = (char*)stnode_data(st_arg2);
if (strcmp(relation_string, "matches") == 0) {
/* Convert to a FT_PCRE */
- fvalue = fvalue_from_string(FT_PCRE, s, dfilter_fail);
+ fvalue = dfilter_fvalue_from_string(dfw, FT_PCRE, s);
} else {
- fvalue = fvalue_from_string(ftype1, s, dfilter_fail);
+ fvalue = dfilter_fvalue_from_string(dfw, ftype1, s);
}
if (!fvalue) {
THROW(TypeError);
@@ -1097,9 +1126,9 @@ check_relation_LHS_FUNCTION(const char *relation_string, FtypeCanFunc can_func,
s = (char*)stnode_data(st_arg2);
if (strcmp(relation_string, "matches") == 0) {
/* Convert to a FT_PCRE */
- fvalue = fvalue_from_unparsed(FT_PCRE, s, FALSE, dfilter_fail);
+ fvalue = dfilter_fvalue_from_unparsed(dfw, FT_PCRE, s, FALSE);
} else {
- fvalue = fvalue_from_unparsed(ftype1, s, allow_partial_value, dfilter_fail);
+ fvalue = dfilter_fvalue_from_unparsed(dfw, ftype1, s, allow_partial_value);
}
if (!fvalue) {
THROW(TypeError);
@@ -1110,10 +1139,10 @@ check_relation_LHS_FUNCTION(const char *relation_string, FtypeCanFunc can_func,
stnode_free(st_arg2);
}
else if (type2 == STTYPE_RANGE) {
- check_drange_sanity(st_arg2);
+ check_drange_sanity(dfw, st_arg2);
if (!is_bytes_type(ftype1)) {
if (!ftype_can_slice(ftype1)) {
- dfilter_fail("Function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
+ dfilter_fail(dfw, "Function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
funcdef->name,
ftype_pretty_name(ftype1));
THROW(TypeError);
@@ -1130,7 +1159,7 @@ check_relation_LHS_FUNCTION(const char *relation_string, FtypeCanFunc can_func,
ftype2 = funcdef2->retval_ftype;
if (!compatible_ftypes(ftype1, ftype2)) {
- dfilter_fail("Return values of function %s (type=%s) and function %s (type=%s) are not of compatible types.",
+ dfilter_fail(dfw, "Return values of function %s (type=%s) and function %s (type=%s) are not of compatible types.",
funcdef->name, ftype_pretty_name(ftype1), funcdef2->name, ftype_pretty_name(ftype2));
THROW(TypeError);
}
@@ -1138,12 +1167,12 @@ check_relation_LHS_FUNCTION(const char *relation_string, FtypeCanFunc can_func,
/* Do this check even though you'd think that if
* they're compatible, then can_func() would pass. */
if (!can_func(ftype2)) {
- dfilter_fail("Return value of %s (type=%s) cannot participate in specified comparison.",
+ dfilter_fail(dfw, "Return value of %s (type=%s) cannot participate in specified comparison.",
funcdef2->name, ftype_pretty_name(ftype2));
THROW(TypeError);
}
- check_function(st_arg2);
+ check_function(dfw, st_arg2);
}
else {
g_assert_not_reached();
@@ -1153,7 +1182,8 @@ check_relation_LHS_FUNCTION(const char *relation_string, FtypeCanFunc can_func,
/* Check the semantics of any relational test. */
static void
-check_relation(const char *relation_string, gboolean allow_partial_value,
+check_relation(dfwork_t *dfw, const char *relation_string,
+ gboolean allow_partial_value,
FtypeCanFunc can_func, stnode_t *st_node,
stnode_t *st_arg1, stnode_t *st_arg2)
{
@@ -1173,30 +1203,30 @@ header_field_info *hfinfo;
if (stnode_type_id(st_arg2) == STTYPE_FIELD) {
hfinfo = (header_field_info*)stnode_data(st_arg2);
if (hfinfo->type == FT_PROTOCOL) {
- dfilter_fail("Protocol (\"%s\") cannot appear on right-hand side of comparison.", hfinfo->abbrev);
+ dfilter_fail(dfw, "Protocol (\"%s\") cannot appear on right-hand side of comparison.", hfinfo->abbrev);
THROW(TypeError);
}
}
switch (stnode_type_id(st_arg1)) {
case STTYPE_FIELD:
- check_relation_LHS_FIELD(relation_string, can_func,
+ check_relation_LHS_FIELD(dfw, relation_string, can_func,
allow_partial_value, st_node, st_arg1, st_arg2);
break;
case STTYPE_STRING:
- check_relation_LHS_STRING(relation_string, can_func,
+ check_relation_LHS_STRING(dfw, relation_string, can_func,
allow_partial_value, st_node, st_arg1, st_arg2);
break;
case STTYPE_RANGE:
- check_relation_LHS_RANGE(relation_string, can_func,
+ check_relation_LHS_RANGE(dfw, relation_string, can_func,
allow_partial_value, st_node, st_arg1, st_arg2);
break;
case STTYPE_UNPARSED:
- check_relation_LHS_UNPARSED(relation_string, can_func,
+ check_relation_LHS_UNPARSED(dfw, relation_string, can_func,
allow_partial_value, st_node, st_arg1, st_arg2);
break;
case STTYPE_FUNCTION:
- check_relation_LHS_FUNCTION(relation_string, can_func,
+ check_relation_LHS_FUNCTION(dfw, relation_string, can_func,
allow_partial_value, st_node, st_arg1, st_arg2);
break;
@@ -1211,7 +1241,7 @@ header_field_info *hfinfo;
/* Check the semantics of any type of TEST */
static void
-check_test(stnode_t *st_node, GPtrArray *deprecated)
+check_test(dfwork_t *dfw, stnode_t *st_node, GPtrArray *deprecated)
{
test_op_t st_op, st_arg_op;
stnode_t *st_arg1, *st_arg2;
@@ -1229,11 +1259,11 @@ check_test(stnode_t *st_node, GPtrArray *deprecated)
break;
case TEST_OP_EXISTS:
- check_exists(st_arg1);
+ check_exists(dfw, st_arg1);
break;
case TEST_OP_NOT:
- semcheck(st_arg1, deprecated);
+ semcheck(dfw, st_arg1, deprecated);
break;
case TEST_OP_AND:
@@ -1254,36 +1284,36 @@ check_test(stnode_t *st_node, GPtrArray *deprecated)
}
}
- semcheck(st_arg1, deprecated);
- semcheck(st_arg2, deprecated);
+ semcheck(dfw, st_arg1, deprecated);
+ semcheck(dfw, st_arg2, deprecated);
break;
case TEST_OP_EQ:
- check_relation("==", FALSE, ftype_can_eq, st_node, st_arg1, st_arg2);
+ check_relation(dfw, "==", FALSE, ftype_can_eq, st_node, st_arg1, st_arg2);
break;
case TEST_OP_NE:
- check_relation("!=", FALSE, ftype_can_ne, st_node, st_arg1, st_arg2);
+ check_relation(dfw, "!=", FALSE, ftype_can_ne, st_node, st_arg1, st_arg2);
break;
case TEST_OP_GT:
- check_relation(">", FALSE, ftype_can_gt, st_node, st_arg1, st_arg2);
+ check_relation(dfw, ">", FALSE, ftype_can_gt, st_node, st_arg1, st_arg2);
break;
case TEST_OP_GE:
- check_relation(">=", FALSE, ftype_can_ge, st_node, st_arg1, st_arg2);
+ check_relation(dfw, ">=", FALSE, ftype_can_ge, st_node, st_arg1, st_arg2);
break;
case TEST_OP_LT:
- check_relation("<", FALSE, ftype_can_lt, st_node, st_arg1, st_arg2);
+ check_relation(dfw, "<", FALSE, ftype_can_lt, st_node, st_arg1, st_arg2);
break;
case TEST_OP_LE:
- check_relation("<=", FALSE, ftype_can_le, st_node, st_arg1, st_arg2);
+ check_relation(dfw, "<=", FALSE, ftype_can_le, st_node, st_arg1, st_arg2);
break;
case TEST_OP_BITWISE_AND:
- check_relation("&", FALSE, ftype_can_bitwise_and, st_node, st_arg1, st_arg2);
+ check_relation(dfw, "&", FALSE, ftype_can_bitwise_and, st_node, st_arg1, st_arg2);
break;
case TEST_OP_CONTAINS:
- check_relation("contains", TRUE, ftype_can_contains, st_node, st_arg1, st_arg2);
+ check_relation(dfw, "contains", TRUE, ftype_can_contains, st_node, st_arg1, st_arg2);
break;
case TEST_OP_MATCHES:
- check_relation("matches", TRUE, ftype_can_matches, st_node, st_arg1, st_arg2); break;
+ check_relation(dfw, "matches", TRUE, ftype_can_matches, st_node, st_arg1, st_arg2); break;
default:
g_assert_not_reached();
@@ -1294,7 +1324,7 @@ check_test(stnode_t *st_node, GPtrArray *deprecated)
/* Check the entire syntax tree. */
static void
-semcheck(stnode_t *st_node, GPtrArray *deprecated)
+semcheck(dfwork_t *dfw, stnode_t *st_node, GPtrArray *deprecated)
{
#ifdef DEBUG_dfilter
static guint i = 0;
@@ -1304,7 +1334,7 @@ semcheck(stnode_t *st_node, GPtrArray *deprecated)
* node will be a TEST node, no matter what. So assert that. */
switch (stnode_type_id(st_node)) {
case STTYPE_TEST:
- check_test(st_node, deprecated);
+ check_test(dfw, st_node, deprecated);
break;
default:
g_assert_not_reached();
@@ -1328,7 +1358,7 @@ dfw_semcheck(dfwork_t *dfw, GPtrArray *deprecated)
* the semantic-checking, the semantic-checking code will
* throw an exception if a problem is found. */
TRY {
- semcheck(dfw->st_root, deprecated);
+ semcheck(dfw, dfw->st_root, deprecated);
}
CATCH(TypeError) {
ok_filter = FALSE;
diff --git a/epan/dfilter/sttype-function.h b/epan/dfilter/sttype-function.h
index 4cd8ca43db..256fd9526a 100644
--- a/epan/dfilter/sttype-function.h
+++ b/epan/dfilter/sttype-function.h
@@ -22,6 +22,7 @@
#ifndef STTYPE_FUNCTION_H
#define STTYPE_FUNCTION_H
+#include "dfilter-int.h"
#include "dfunctions.h"
/* Set the parameters for a function stnode_t. */
diff --git a/epan/dissectors/packet-ncp2222.inc b/epan/dissectors/packet-ncp2222.inc
index 9ff102d081..e12e0e4ddd 100644
--- a/epan/dissectors/packet-ncp2222.inc
+++ b/epan/dissectors/packet-ncp2222.inc
@@ -7405,12 +7405,14 @@ static void
ncp2222_compile_dfilters(void)
{
int i;
+ gchar *err_msg;
for (i = 0; i < NUM_REQ_CONDS; i++) {
if (!dfilter_compile((const gchar*)req_conds[i].dfilter_text,
- &req_conds[i].dfilter)) {
- g_message("NCP dissector failed to compile dfilter: %s\n",
- req_conds[i].dfilter_text);
+ &req_conds[i].dfilter, &err_msg)) {
+ g_message("NCP dissector failed to compile dfilter \"%s\": %s\n",
+ req_conds[i].dfilter_text, err_msg);
+ g_free(err_msg);
g_assert_not_reached();
}
}
diff --git a/epan/ftypes/ftype-bytes.c b/epan/ftypes/ftype-bytes.c
index 75552e9115..fc42f0c9f0 100644
--- a/epan/ftypes/ftype-bytes.c
+++ b/epan/ftypes/ftype-bytes.c
@@ -232,7 +232,7 @@ value_get(fvalue_t *fv)
}
static gboolean
-bytes_from_string(fvalue_t *fv, const char *s, LogFunc logfunc _U_)
+bytes_from_string(fvalue_t *fv, const char *s, gchar **err_msg _U_)
{
GByteArray *bytes;
@@ -248,7 +248,7 @@ bytes_from_string(fvalue_t *fv, const char *s, LogFunc logfunc _U_)
}
static gboolean
-bytes_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
+bytes_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
{
GByteArray *bytes;
gboolean res;
@@ -258,8 +258,8 @@ bytes_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U
res = hex_str_to_bytes(s, bytes, TRUE);
if (!res) {
- if (logfunc != NULL)
- logfunc("\"%s\" is not a valid byte string.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" is not a valid byte string.", s);
g_byte_array_free(bytes, TRUE);
return FALSE;
}
@@ -273,22 +273,26 @@ bytes_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U
}
static gboolean
-ax25_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, LogFunc logfunc)
+ax25_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
{
/*
- * Don't log a message if this fails; we'll try looking it
- * up as another way if it does, and if that fails,
- * we'll log a message.
+ * Don't request an error message if bytes_from_unparsed fails;
+ * if it does, we'll report an error specific to this address
+ * type.
*/
if (bytes_from_unparsed(fv, s, TRUE, NULL)) {
if (fv->value.bytes->len > FT_AX25_ADDR_LEN) {
- logfunc("\"%s\" contains too many bytes to be a valid AX.25 address.",
- s);
+ if (err_msg != NULL) {
+ *err_msg = g_strdup_printf("\"%s\" contains too many bytes to be a valid AX.25 address.",
+ s);
+ }
return FALSE;
}
else if (fv->value.bytes->len < FT_AX25_ADDR_LEN && !allow_partial_value) {
- logfunc("\"%s\" contains too few bytes to be a valid AX.25 address.",
- s);
+ if (err_msg != NULL) {
+ *err_msg = g_strdup_printf("\"%s\" contains too few bytes to be a valid AX.25 address.",
+ s);
+ }
return FALSE;
}
@@ -326,27 +330,32 @@ ax25_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, Lo
*
* http://www.itu.int/ITU-R/terrestrial/docs/fixedmobile/fxm-art19-sec3.pdf
*/
- logfunc("\"%s\" is not a valid AX.25 address.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" is not a valid AX.25 address.", s);
return FALSE;
}
static gboolean
-vines_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, LogFunc logfunc)
+vines_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
{
/*
- * Don't log a message if this fails; we'll try looking it
- * up as another way if it does, and if that fails,
- * we'll log a message.
+ * Don't request an error message if bytes_from_unparsed fails;
+ * if it does, we'll report an error specific to this address
+ * type.
*/
if (bytes_from_unparsed(fv, s, TRUE, NULL)) {
if (fv->value.bytes->len > FT_VINES_ADDR_LEN) {
- logfunc("\"%s\" contains too many bytes to be a valid Vines address.",
- s);
+ if (err_msg != NULL) {
+ *err_msg = g_strdup_printf("\"%s\" contains too many bytes to be a valid Vines address.",
+ s);
+ }
return FALSE;
}
else if (fv->value.bytes->len < FT_VINES_ADDR_LEN && !allow_partial_value) {
- logfunc("\"%s\" contains too few bytes to be a valid Vines address.",
- s);
+ if (err_msg != NULL) {
+ *err_msg = g_strdup_printf("\"%s\" contains too few bytes to be a valid Vines address.",
+ s);
+ }
return FALSE;
}
@@ -355,29 +364,34 @@ vines_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, L
/* XXX - need better validation of Vines address */
- logfunc("\"%s\" is not a valid Vines address.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" is not a valid Vines address.", s);
return FALSE;
}
static gboolean
-ether_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, LogFunc logfunc)
+ether_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
{
guint8 *mac;
/*
- * Don't log a message if this fails; we'll try looking it
- * up as an Ethernet host name if it does, and if that fails,
- * we'll log a message.
+ * Don't request an error message if bytes_from_unparsed fails;
+ * if it does, we'll report an error specific to this address
+ * type.
*/
if (bytes_from_unparsed(fv, s, TRUE, NULL)) {
if (fv->value.bytes->len > FT_ETHER_LEN) {
- logfunc("\"%s\" contains too many bytes to be a valid Ethernet address.",
- s);
+ if (err_msg != NULL) {
+ *err_msg = g_strdup_printf("\"%s\" contains too many bytes to be a valid Ethernet address.",
+ s);
+ }
return FALSE;
}
else if (fv->value.bytes->len < FT_ETHER_LEN && !allow_partial_value) {
- logfunc("\"%s\" contains too few bytes to be a valid Ethernet address.",
- s);
+ if (err_msg != NULL) {
+ *err_msg = g_strdup_printf("\"%s\" contains too few bytes to be a valid Ethernet address.",
+ s);
+ }
return FALSE;
}
@@ -386,8 +400,10 @@ ether_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, L
mac = get_ether_addr(s);
if (!mac) {
- logfunc("\"%s\" is not a valid hostname or Ethernet address.",
- s);
+ if (err_msg != NULL) {
+ *err_msg = g_strdup_printf("\"%s\" is not a valid hostname or Ethernet address.",
+ s);
+ }
return FALSE;
}
@@ -396,28 +412,29 @@ ether_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, L
}
static gboolean
-oid_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
+oid_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
{
GByteArray *bytes;
gboolean res;
+#if 0
/*
* Don't log a message if this fails; we'll try looking it
* up as an OID if it does, and if that fails,
* we'll log a message.
*/
- /* do not try it as '.' is handled as valid separator for hexbytes :(
+ /* do not try it as '.' is handled as valid separator for hexbytes :( */
if (bytes_from_unparsed(fv, s, TRUE, NULL)) {
return TRUE;
}
- */
+#endif
bytes = g_byte_array_new();
res = oid_str_to_bytes(s, bytes);
if (!res) {
- if (logfunc != NULL)
- logfunc("\"%s\" is not a valid OBJECT IDENTIFIER.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" is not a valid OBJECT IDENTIFIER.", s);
g_byte_array_free(bytes, TRUE);
return FALSE;
}
@@ -430,22 +447,16 @@ oid_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_,
}
static gboolean
-rel_oid_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
+rel_oid_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
{
GByteArray *bytes;
gboolean res;
-
- /*
- * Don't log a message if this fails; we'll try looking it
- * up as an OID if it does, and if that fails,
- * we'll log a message.
- */
bytes = g_byte_array_new();
res = rel_oid_str_to_bytes(s, bytes, FALSE);
if (!res) {
- if (logfunc != NULL)
- logfunc("\"%s\" is not a valid RELATIVE-OID.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" is not a valid RELATIVE-OID.", s);
g_byte_array_free(bytes, TRUE);
return FALSE;
}
@@ -458,17 +469,19 @@ rel_oid_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value
}
static gboolean
-system_id_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
+system_id_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
{
/*
- * Don't log a message if this fails; we'll try looking it
- * up as another way if it does, and if that fails,
- * we'll log a message.
+ * Don't request an error message if bytes_from_unparsed fails;
+ * if it does, we'll report an error specific to this address
+ * type.
*/
if (bytes_from_unparsed(fv, s, TRUE, NULL)) {
if (fv->value.bytes->len > MAX_SYSTEMID_LEN) {
- logfunc("\"%s\" contains too many bytes to be a valid OSI System-ID.",
- s);
+ if (err_msg != NULL) {
+ *err_msg = g_strdup_printf("\"%s\" contains too many bytes to be a valid OSI System-ID.",
+ s);
+ }
return FALSE;
}
@@ -477,22 +490,25 @@ system_id_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_valu
/* XXX - need better validation of OSI System-ID address */
- logfunc("\"%s\" is not a valid OSI System-ID.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" is not a valid OSI System-ID.", s);
return FALSE;
}
static gboolean
-fcwwn_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
+fcwwn_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
{
/*
- * Don't log a message if this fails; we'll try looking it
- * up as another way if it does, and if that fails,
- * we'll log a message.
+ * Don't request an error message if bytes_from_unparsed fails;
+ * if it does, we'll report an error specific to this address
+ * type.
*/
if (bytes_from_unparsed(fv, s, TRUE, NULL)) {
if (fv->value.bytes->len > FT_FCWWN_LEN) {
- logfunc("\"%s\" contains too many bytes to be a valid FCWWN.",
- s);
+ if (err_msg != NULL) {
+ *err_msg = g_strdup_printf("\"%s\" contains too many bytes to be a valid FCWWN.",
+ s);
+ }
return FALSE;
}
@@ -501,7 +517,8 @@ fcwwn_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U
/* XXX - need better validation of FCWWN address */
- logfunc("\"%s\" is not a valid FCWWN.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" is not a valid FCWWN.", s);
return FALSE;
}
diff --git a/epan/ftypes/ftype-double.c b/epan/ftypes/ftype-double.c
index ef1991815e..d4778b55ce 100644
--- a/epan/ftypes/ftype-double.c
+++ b/epan/ftypes/ftype-double.c
@@ -47,7 +47,7 @@ value_get_floating(fvalue_t *fv)
}
static gboolean
-val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
+val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
{
char *endptr = NULL;
@@ -55,19 +55,23 @@ val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_,
if (endptr == s || *endptr != '\0') {
/* This isn't a valid number. */
- logfunc("\"%s\" is not a valid number.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" is not a valid number.", s);
return FALSE;
}
if (errno == ERANGE) {
if (fv->value.floating == 0) {
- logfunc("\"%s\" causes floating-point underflow.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" causes floating-point underflow.", s);
}
else if (fv->value.floating == HUGE_VAL) {
- logfunc("\"%s\" causes floating-point overflow.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" causes floating-point overflow.", s);
}
else {
- logfunc("\"%s\" is not a valid floating-point number.",
- s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" is not a valid floating-point number.",
+ s);
}
return FALSE;
}
diff --git a/epan/ftypes/ftype-guid.c b/epan/ftypes/ftype-guid.c
index 290738ae20..20d448d078 100644
--- a/epan/ftypes/ftype-guid.c
+++ b/epan/ftypes/ftype-guid.c
@@ -84,12 +84,13 @@ get_guid(const char *s, e_guid_t *guid)
}
static gboolean
-guid_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
+guid_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
{
e_guid_t guid;
if (!get_guid(s, &guid)) {
- logfunc("\"%s\" is not a valid GUID.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" is not a valid GUID.", s);
return FALSE;
}
diff --git a/epan/ftypes/ftype-integer.c b/epan/ftypes/ftype-integer.c
index 7b1e8577e4..7fe8342cb6 100644
--- a/epan/ftypes/ftype-integer.c
+++ b/epan/ftypes/ftype-integer.c
@@ -62,7 +62,7 @@ get_sinteger(fvalue_t *fv)
static gboolean
-uint_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc,
+uint_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg,
guint32 max)
{
unsigned long value;
@@ -73,8 +73,8 @@ uint_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_
* Probably a negative integer, but will be
* "converted in the obvious manner" by strtoul().
*/
- if (logfunc != NULL)
- logfunc("\"%s\" too small for this field, minimum 0.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" too small for this field, minimum 0.", s);
return FALSE;
}
@@ -83,14 +83,14 @@ uint_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_
if (errno == EINVAL || endptr == s || *endptr != '\0') {
/* This isn't a valid number. */
- if (logfunc != NULL)
- logfunc("\"%s\" is not a valid number.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" is not a valid number.", s);
return FALSE;
}
if (errno == ERANGE) {
- if (logfunc != NULL) {
+ if (err_msg != NULL) {
if (value == ULONG_MAX) {
- logfunc("\"%s\" causes an integer overflow.",
+ *err_msg = g_strdup_printf("\"%s\" causes an integer overflow.",
s);
}
else {
@@ -98,15 +98,15 @@ uint_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_
* XXX - can "strtoul()" set errno to
* ERANGE without returning ULONG_MAX?
*/
- logfunc("\"%s\" is not an integer.", s);
+ *err_msg = g_strdup_printf("\"%s\" is not an integer.", s);
}
}
return FALSE;
}
if (value > max) {
- if (logfunc != NULL)
- logfunc("\"%s\" too big for this field, maximum %u.", s, max);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" too big for this field, maximum %u.", s, max);
return FALSE;
}
@@ -115,31 +115,31 @@ uint_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_
}
static gboolean
-uint32_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, LogFunc logfunc)
+uint32_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
{
- return uint_from_unparsed (fv, s, allow_partial_value, logfunc, G_MAXUINT32);
+ return uint_from_unparsed (fv, s, allow_partial_value, err_msg, G_MAXUINT32);
}
static gboolean
-uint24_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, LogFunc logfunc)
+uint24_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
{
- return uint_from_unparsed (fv, s, allow_partial_value, logfunc, 0xFFFFFF);
+ return uint_from_unparsed (fv, s, allow_partial_value, err_msg, 0xFFFFFF);
}
static gboolean
-uint16_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, LogFunc logfunc)
+uint16_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
{
- return uint_from_unparsed (fv, s, allow_partial_value, logfunc, G_MAXUINT16);
+ return uint_from_unparsed (fv, s, allow_partial_value, err_msg, G_MAXUINT16);
}
static gboolean
-uint8_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, LogFunc logfunc)
+uint8_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
{
- return uint_from_unparsed (fv, s, allow_partial_value, logfunc, G_MAXUINT8);
+ return uint_from_unparsed (fv, s, allow_partial_value, err_msg, G_MAXUINT8);
}
static gboolean
-sint_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc,
+sint_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg,
gint32 max, gint32 min)
{
long value;
@@ -150,8 +150,8 @@ sint_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_
* Probably a positive integer > G_MAXINT32, but will be
* "converted in the obvious manner" by strtol().
*/
- if (logfunc != NULL)
- logfunc("\"%s\" causes an integer overflow.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" causes an integer overflow.", s);
return FALSE;
}
@@ -160,37 +160,37 @@ sint_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_
if (errno == EINVAL || endptr == s || *endptr != '\0') {
/* This isn't a valid number. */
- if (logfunc != NULL)
- logfunc("\"%s\" is not a valid number.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" is not a valid number.", s);
return FALSE;
}
if (errno == ERANGE) {
- if (logfunc != NULL) {
+ if (err_msg != NULL) {
if (value == LONG_MAX) {
- logfunc("\"%s\" causes an integer overflow.", s);
+ *err_msg = g_strdup_printf("\"%s\" causes an integer overflow.", s);
}
else if (value == LONG_MIN) {
- logfunc("\"%s\" causes an integer underflow.", s);
+ *err_msg = g_strdup_printf("\"%s\" causes an integer underflow.", s);
}
else {
/*
* XXX - can "strtol()" set errno to
* ERANGE without returning ULONG_MAX?
*/
- logfunc("\"%s\" is not an integer.", s);
+ *err_msg = g_strdup_printf("\"%s\" is not an integer.", s);
}
}
return FALSE;
}
if (value > max) {
- if (logfunc != NULL)
- logfunc("\"%s\" too big for this field, maximum %d.",
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" too big for this field, maximum %d.",
s, max);
return FALSE;
} else if (value < min) {
- if (logfunc != NULL)
- logfunc("\"%s\" too small for this field, minimum %d.",
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" too small for this field, minimum %d.",
s, min);
return FALSE;
}
@@ -200,27 +200,27 @@ sint_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_
}
static gboolean
-sint32_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, LogFunc logfunc)
+sint32_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
{
- return sint_from_unparsed (fv, s, allow_partial_value, logfunc, G_MAXINT32, G_MININT32);
+ return sint_from_unparsed (fv, s, allow_partial_value, err_msg, G_MAXINT32, G_MININT32);
}
static gboolean
-sint24_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, LogFunc logfunc)
+sint24_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
{
- return sint_from_unparsed (fv, s, allow_partial_value, logfunc, 0x7FFFFF, -0x800000);
+ return sint_from_unparsed (fv, s, allow_partial_value, err_msg, 0x7FFFFF, -0x800000);
}
static gboolean
-sint16_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, LogFunc logfunc)
+sint16_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
{
- return sint_from_unparsed (fv, s, allow_partial_value, logfunc, G_MAXINT16, G_MININT16);
+ return sint_from_unparsed (fv, s, allow_partial_value, err_msg, G_MAXINT16, G_MININT16);
}
static gboolean
-sint8_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, LogFunc logfunc)
+sint8_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
{
- return sint_from_unparsed (fv, s, allow_partial_value, logfunc, G_MAXINT8, G_MININT8);
+ return sint_from_unparsed (fv, s, allow_partial_value, err_msg, G_MAXINT8, G_MININT8);
}
static int
@@ -256,15 +256,15 @@ uinteger_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, int field_display _U_, char *
}
static gboolean
-ipxnet_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
+ipxnet_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
{
guint32 val;
gboolean known;
/*
- * Don't log a message if this fails; we'll try looking it
- * up as an IPX network name if it does, and if that fails,
- * we'll log a message.
+ * Don't request an errror message if uint32_from_unparsed fails;
+ * if it does, we'll try looking it up as an IPX network name, and
+ * if that fails, we'll report an error message for that.
*/
if (uint32_from_unparsed(fv, s, TRUE, NULL)) {
return TRUE;
@@ -276,7 +276,8 @@ ipxnet_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _
return TRUE;
}
- logfunc("\"%s\" is not a valid IPX network name or address.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" is not a valid IPX network name or address.", s);
return FALSE;
}
@@ -377,7 +378,7 @@ get_integer64(fvalue_t *fv)
}
static gboolean
-uint64_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
+uint64_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
{
guint64 value;
char *endptr;
@@ -387,8 +388,8 @@ uint64_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _
* Probably a negative integer, but will be
* "converted in the obvious manner" by g_ascii_strtoull().
*/
- if (logfunc != NULL)
- logfunc("\"%s\" causes an integer underflow.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" causes an integer underflow.", s);
return FALSE;
}
@@ -397,21 +398,21 @@ uint64_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _
if (errno == EINVAL || endptr == s || *endptr != '\0') {
/* This isn't a valid number. */
- if (logfunc != NULL)
- logfunc("\"%s\" is not a valid number.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" is not a valid number.", s);
return FALSE;
}
if (errno == ERANGE) {
- if (logfunc != NULL) {
+ if (err_msg != NULL) {
if (value == G_MAXUINT64) {
- logfunc("\"%s\" causes an integer overflow.", s);
+ *err_msg = g_strdup_printf("\"%s\" causes an integer overflow.", s);
}
else {
/*
* XXX - can "strtoul()" set errno to
* ERANGE without returning ULONG_MAX?
*/
- logfunc("\"%s\" is not an integer.", s);
+ *err_msg = g_strdup_printf("\"%s\" is not an integer.", s);
}
}
return FALSE;
@@ -422,7 +423,7 @@ uint64_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _
}
static gboolean
-sint64_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
+sint64_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
{
gint64 value;
char *endptr;
@@ -432,8 +433,8 @@ sint64_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _
* Probably a positive integer > G_MAXINT64, but will be
* "converted in the obvious manner" by g_ascii_strtoll().
*/
- if (logfunc != NULL)
- logfunc("\"%s\" causes an integer overflow.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" causes an integer overflow.", s);
return FALSE;
}
@@ -442,24 +443,24 @@ sint64_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _
if (errno == EINVAL || endptr == s || *endptr != '\0') {
/* This isn't a valid number. */
- if (logfunc != NULL)
- logfunc("\"%s\" is not a valid number.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" is not a valid number.", s);
return FALSE;
}
if (errno == ERANGE) {
- if (logfunc != NULL) {
+ if (err_msg != NULL) {
if (value == G_MAXINT64) {
- logfunc("\"%s\" causes an integer overflow.", s);
+ *err_msg = g_strdup_printf("\"%s\" causes an integer overflow.", s);
}
else if (value == G_MININT64) {
- logfunc("\"%s\" causes an integer underflow.", s);
+ *err_msg = g_strdup_printf("\"%s\" causes an integer underflow.", s);
}
else {
/*
* XXX - can "strtol()" set errno to
* ERANGE without returning LONG_MAX?
*/
- logfunc("\"%s\" is not an integer.", s);
+ *err_msg = g_strdup_printf("\"%s\" is not an integer.", s);
}
}
return FALSE;
@@ -611,19 +612,19 @@ bool_ne(const fvalue_t *a, const fvalue_t *b)
/* EUI64-specific */
static gboolean
-eui64_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
+eui64_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
{
-
/*
- * Don't log a message if this fails; we'll try looking it
- * up as an EUI64 Address if it does, and if that fails,
- * we'll log a message.
+ * Don't request an error message if uint64_from_unparsed fails;
+ * if it does, we'll report an error specific to this address
+ * type.
*/
if (uint64_from_unparsed(fv, s, TRUE, NULL)) {
return TRUE;
}
- logfunc("\"%s\" is not a valid EUI64 Address", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" is not a valid EUI64 Address", s);
return FALSE;
}
diff --git a/epan/ftypes/ftype-ipv4.c b/epan/ftypes/ftype-ipv4.c
index d7dada34ea..7f46a35e12 100644
--- a/epan/ftypes/ftype-ipv4.c
+++ b/epan/ftypes/ftype-ipv4.c
@@ -41,7 +41,7 @@ value_get(fvalue_t *fv)
}
static gboolean
-val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
+val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
{
guint32 addr;
unsigned int nmask_bits;
@@ -64,7 +64,10 @@ val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_,
}
if (!get_host_ipaddr(addr_str, &addr)) {
- logfunc("\"%s\" is not a valid hostname or IPv4 address.", addr_str);
+ if (err_msg != NULL) {
+ *err_msg = g_strdup_printf("\"%s\" is not a valid hostname or IPv4 address.",
+ addr_str);
+ }
if (free_addr_str)
wmem_free(NULL, addr_str);
return FALSE;
@@ -80,7 +83,7 @@ val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_,
net_str = has_slash + 1;
/* XXX - this is inefficient */
- nmask_fvalue = fvalue_from_unparsed(FT_UINT32, net_str, FALSE, logfunc);
+ nmask_fvalue = fvalue_from_unparsed(FT_UINT32, net_str, FALSE, err_msg);
if (!nmask_fvalue) {
return FALSE;
}
@@ -88,8 +91,10 @@ val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_,
FVALUE_FREE(nmask_fvalue);
if (nmask_bits > 32) {
- logfunc("Netmask bits in a CIDR IPv4 address should be <= 32, not %u",
- nmask_bits);
+ if (err_msg != NULL) {
+ *err_msg = g_strdup_printf("Netmask bits in a CIDR IPv4 address should be <= 32, not %u",
+ nmask_bits);
+ }
return FALSE;
}
ipv4_addr_set_netmask_bits(&fv->value.ipv4, nmask_bits);
diff --git a/epan/ftypes/ftype-ipv6.c b/epan/ftypes/ftype-ipv6.c
index bc72f58144..b69139df11 100644
--- a/epan/ftypes/ftype-ipv6.c
+++ b/epan/ftypes/ftype-ipv6.c
@@ -34,7 +34,7 @@ ipv6_fvalue_set(fvalue_t *fv, const guint8 *value)
}
static gboolean
-ipv6_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
+ipv6_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
{
const char *has_slash;
char *addr_str;
@@ -51,7 +51,8 @@ ipv6_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_
addr_str = (char*)s;
if (!get_host_ipaddr6(addr_str, &(fv->value.ipv6.addr))) {
- logfunc("\"%s\" is not a valid hostname or IPv6 address.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" is not a valid hostname or IPv6 address.", s);
if (free_addr_str)
wmem_free(NULL, addr_str);
return FALSE;
@@ -63,7 +64,7 @@ ipv6_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_
/* If prefix */
if (has_slash) {
/* XXX - this is inefficient */
- nmask_fvalue = fvalue_from_unparsed(FT_UINT32, has_slash+1, FALSE, logfunc);
+ nmask_fvalue = fvalue_from_unparsed(FT_UINT32, has_slash+1, FALSE, err_msg);
if (!nmask_fvalue) {
return FALSE;
}
@@ -71,8 +72,10 @@ ipv6_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_
FVALUE_FREE(nmask_fvalue);
if (nmask_bits > 128) {
- logfunc("Prefix in a IPv6 address should be <= 128, not %u",
- nmask_bits);
+ if (err_msg != NULL) {
+ *err_msg = g_strdup_printf("Prefix in a IPv6 address should be <= 128, not %u",
+ nmask_bits);
+ }
return FALSE;
}
fv->value.ipv6.prefix = nmask_bits;
diff --git a/epan/ftypes/ftype-pcre.c b/epan/ftypes/ftype-pcre.c
index f324370527..88ecb104d4 100644
--- a/epan/ftypes/ftype-pcre.c
+++ b/epan/ftypes/ftype-pcre.c
@@ -68,9 +68,10 @@ raw_flag_needed(const gchar *pattern)
}
/* Generate a FT_PCRE from a parsed string pattern.
- * Uses the specified logfunc() to report errors. */
+ * On failure, if err_msg is non-null, set *err_msg to point to a
+ * g_malloc()ed error message. */
static gboolean
-val_from_string(fvalue_t *fv, const char *pattern, LogFunc logfunc)
+val_from_string(fvalue_t *fv, const char *pattern, gchar **err_msg)
{
GError *regex_error = NULL;
GRegexCompileFlags cflags = G_REGEX_OPTIMIZE;
@@ -93,8 +94,8 @@ val_from_string(fvalue_t *fv, const char *pattern, LogFunc logfunc)
);
if (regex_error) {
- if (logfunc) {
- logfunc(regex_error->message);
+ if (err_msg) {
+ *err_msg = g_strdup(regex_error->message);
}
g_error_free(regex_error);
if (fv->value.re) {
@@ -106,13 +107,14 @@ val_from_string(fvalue_t *fv, const char *pattern, LogFunc logfunc)
}
/* Generate a FT_PCRE from an unparsed string pattern.
- * Uses the specified logfunc() to report errors. */
+ * On failure, if err_msg is non-null, set *err_msg to point to a
+ * g_malloc()ed error message. */
static gboolean
-val_from_unparsed(fvalue_t *fv, const char *pattern, gboolean allow_partial_value _U_, LogFunc logfunc)
+val_from_unparsed(fvalue_t *fv, const char *pattern, gboolean allow_partial_value _U_, gchar **err_msg)
{
g_assert(! allow_partial_value);
- return val_from_string(fv, pattern, logfunc);
+ return val_from_string(fv, pattern, err_msg);
}
static int
diff --git a/epan/ftypes/ftype-string.c b/epan/ftypes/ftype-string.c
index ff3b9c3c6c..d7d0a0060e 100644
--- a/epan/ftypes/ftype-string.c
+++ b/epan/ftypes/ftype-string.c
@@ -89,7 +89,7 @@ value_get(fvalue_t *fv)
}
static gboolean
-val_from_string(fvalue_t *fv, const char *s, LogFunc logfunc _U_)
+val_from_string(fvalue_t *fv, const char *s, gchar **err_msg _U_)
{
/* Free up the old value, if we have one */
string_fvalue_free(fv);
@@ -99,7 +99,7 @@ val_from_string(fvalue_t *fv, const char *s, LogFunc logfunc _U_)
}
static gboolean
-val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
+val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
{
fvalue_t *fv_bytes;
@@ -123,7 +123,7 @@ val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_,
}
/* Just turn it into a string */
- return val_from_string(fv, s, logfunc);
+ return val_from_string(fv, s, err_msg);
}
static guint
diff --git a/epan/ftypes/ftype-time.c b/epan/ftypes/ftype-time.c
index 09ae23f869..6ee8907142 100644
--- a/epan/ftypes/ftype-time.c
+++ b/epan/ftypes/ftype-time.c
@@ -168,7 +168,7 @@ get_nsecs(const char *startp, int *nsecs)
}
static gboolean
-relative_val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
+relative_val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
{
const char *curptr;
char *endptr;
@@ -227,14 +227,14 @@ relative_val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_v
return TRUE;
fail:
- if (logfunc != NULL)
- logfunc("\"%s\" is not a valid time.", s);
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" is not a valid time.", s);
return FALSE;
}
static gboolean
-absolute_val_from_string(fvalue_t *fv, const char *s, LogFunc logfunc)
+absolute_val_from_string(fvalue_t *fv, const char *s, gchar **err_msg)
{
struct tm tm;
char *curptr;
@@ -291,16 +291,16 @@ absolute_val_from_string(fvalue_t *fv, const char *s, LogFunc logfunc)
return TRUE;
fail:
- if (logfunc != NULL)
- logfunc("\"%s\" is not a valid absolute time. Example: \"Nov 12, 1999 08:55:44.123\" or \"2011-07-04 12:34:56\"",
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("\"%s\" is not a valid absolute time. Example: \"Nov 12, 1999 08:55:44.123\" or \"2011-07-04 12:34:56\"",
s);
return FALSE;
}
static gboolean
-absolute_val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
+absolute_val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
{
- return absolute_val_from_string(fv, s, logfunc);
+ return absolute_val_from_string(fv, s, err_msg);
}
static void
diff --git a/epan/ftypes/ftype-tvbuff.c b/epan/ftypes/ftype-tvbuff.c
index 714f545dfe..950379a879 100644
--- a/epan/ftypes/ftype-tvbuff.c
+++ b/epan/ftypes/ftype-tvbuff.c
@@ -61,7 +61,7 @@ free_tvb_data(void *data)
}
static gboolean
-val_from_string(fvalue_t *fv, const char *s, LogFunc logfunc _U_)
+val_from_string(fvalue_t *fv, const char *s, gchar **err_msg _U_)
{
tvbuff_t *new_tvb;
guint8 *private_data;
@@ -85,7 +85,7 @@ val_from_string(fvalue_t *fv, const char *s, LogFunc logfunc _U_)
}
static gboolean
-val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
+val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
{
fvalue_t *fv_bytes;
tvbuff_t *new_tvb;
@@ -114,7 +114,7 @@ val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_,
}
/* Treat it as a string. */
- return val_from_string(fv, s, logfunc);
+ return val_from_string(fv, s, err_msg);
}
static int
diff --git a/epan/ftypes/ftypes-int.h b/epan/ftypes/ftypes-int.h
index c2aaf11427..020a571f21 100644
--- a/epan/ftypes/ftypes-int.h
+++ b/epan/ftypes/ftypes-int.h
@@ -48,8 +48,8 @@ void ftype_register_pcre(void);
typedef void (*FvalueNewFunc)(fvalue_t*);
typedef void (*FvalueFreeFunc)(fvalue_t*);
-typedef gboolean (*FvalueFromUnparsed)(fvalue_t*, const char*, gboolean, LogFunc);
-typedef gboolean (*FvalueFromString)(fvalue_t*, const char*, LogFunc);
+typedef gboolean (*FvalueFromUnparsed)(fvalue_t*, const char*, gboolean, gchar **);
+typedef gboolean (*FvalueFromString)(fvalue_t*, const char*, gchar **);
typedef void (*FvalueToStringRepr)(fvalue_t*, ftrepr_t, int field_display, char*volatile);
typedef int (*FvalueStringReprLen)(fvalue_t*, ftrepr_t, int field_display);
diff --git a/epan/ftypes/ftypes.c b/epan/ftypes/ftypes.c
index a06594392c..7f4aba791c 100644
--- a/epan/ftypes/ftypes.c
+++ b/epan/ftypes/ftypes.c
@@ -288,38 +288,48 @@ fvalue_init(fvalue_t *fv, ftenum_t ftype)
}
fvalue_t*
-fvalue_from_unparsed(ftenum_t ftype, const char *s, gboolean allow_partial_value, LogFunc logfunc)
+fvalue_from_unparsed(ftenum_t ftype, const char *s, gboolean allow_partial_value, gchar **err_msg)
{
fvalue_t *fv;
fv = fvalue_new(ftype);
if (fv->ftype->val_from_unparsed) {
- if (fv->ftype->val_from_unparsed(fv, s, allow_partial_value, logfunc)) {
+ if (fv->ftype->val_from_unparsed(fv, s, allow_partial_value, err_msg)) {
+ /* Success */
+ if (err_msg != NULL)
+ *err_msg = NULL;
return fv;
}
}
else {
- logfunc("\"%s\" cannot be converted to %s.",
- s, ftype_pretty_name(ftype));
+ if (err_msg != NULL) {
+ *err_msg = g_strdup_printf("\"%s\" cannot be converted to %s.",
+ s, ftype_pretty_name(ftype));
+ }
}
FVALUE_FREE(fv);
return NULL;
}
fvalue_t*
-fvalue_from_string(ftenum_t ftype, const char *s, LogFunc logfunc)
+fvalue_from_string(ftenum_t ftype, const char *s, gchar **err_msg)
{
fvalue_t *fv;
fv = fvalue_new(ftype);
if (fv->ftype->val_from_string) {
- if (fv->ftype->val_from_string(fv, s, logfunc)) {
+ if (fv->ftype->val_from_string(fv, s, err_msg)) {
+ /* Success */
+ if (err_msg != NULL)
+ *err_msg = NULL;
return fv;
}
}
else {
- logfunc("\"%s\" cannot be converted to %s.",
- s, ftype_pretty_name(ftype));
+ if (err_msg != NULL) {
+ *err_msg = g_strdup_printf("\"%s\" cannot be converted to %s.",
+ s, ftype_pretty_name(ftype));
+ }
}
FVALUE_FREE(fv);
return NULL;
diff --git a/epan/ftypes/ftypes.h b/epan/ftypes/ftypes.h
index 6e969043ca..d830722fc4 100644
--- a/epan/ftypes/ftypes.h
+++ b/epan/ftypes/ftypes.h
@@ -203,8 +203,6 @@ typedef struct _fvalue_t {
} fvalue_t;
-typedef void (*LogFunc)(const char*,...);
-
fvalue_t*
fvalue_new(ftenum_t ftype);
@@ -213,10 +211,10 @@ fvalue_init(fvalue_t *fv, ftenum_t ftype);
WS_DLL_PUBLIC
fvalue_t*
-fvalue_from_unparsed(ftenum_t ftype, const char *s, gboolean allow_partial_value, LogFunc logfunc);
+fvalue_from_unparsed(ftenum_t ftype, const char *s, gboolean allow_partial_value, gchar **err_msg);
fvalue_t*
-fvalue_from_string(ftenum_t ftype, const char *s, LogFunc logfunc);
+fvalue_from_string(ftenum_t ftype, const char *s, gchar **err_msg);
/* Returns the length of the string required to hold the
* string representation of the the field value.
diff --git a/epan/funnel.h b/epan/funnel.h
index 2b2282ab75..3d66f54c63 100644
--- a/epan/funnel.h
+++ b/epan/funnel.h
@@ -79,7 +79,7 @@ typedef struct _funnel_ops_t {
gchar * (*get_filter)(void);
void (*set_filter)(const char*);
void (*set_color_filter_slot)(guint8 flit_nr, const gchar* filter);
- gboolean (*open_file)(const char* fname, const char* filter, const char** error);
+ gboolean (*open_file)(const char* fname, const char* filter, char** error);
void (*reload)(void);
void (*apply_filter)(void);
diff --git a/epan/tap.c b/epan/tap.c
index d2b6fe9183..ba4a1839e5 100644
--- a/epan/tap.c
+++ b/epan/tap.c
@@ -472,6 +472,7 @@ register_tap_listener(const char *tapname, void *tapdata, const char *fstring,
tap_listener_t *tl;
int tap_id;
GString *error_string;
+ gchar *err_msg;
tap_id=find_tap_id(tapname);
if(!tap_id){
@@ -485,11 +486,12 @@ register_tap_listener(const char *tapname, void *tapdata, const char *fstring,
tl->needs_redraw=TRUE;
tl->flags=flags;
if(fstring){
- if(!dfilter_compile(fstring, &tl->code)){
+ if(!dfilter_compile(fstring, &tl->code, &err_msg)){
error_string = g_string_new("");
g_string_printf(error_string,
"Filter \"%s\" is invalid - %s",
- fstring, dfilter_error_msg);
+ fstring, err_msg);
+ g_free(err_msg);
g_free(tl);
return error_string;
}
@@ -514,6 +516,7 @@ set_tap_dfilter(void *tapdata, const char *fstring)
{
tap_listener_t *tl=NULL,*tl2;
GString *error_string;
+ gchar *err_msg;
if(!tap_listener_queue){
return NULL;
@@ -538,11 +541,12 @@ set_tap_dfilter(void *tapdata, const char *fstring)
}
tl->needs_redraw=TRUE;
if(fstring){
- if(!dfilter_compile(fstring, &tl->code)){
+ if(!dfilter_compile(fstring, &tl->code, &err_msg)){
error_string = g_string_new("");
g_string_printf(error_string,
"Filter \"%s\" is invalid - %s",
- fstring, dfilter_error_msg);
+ fstring, err_msg);
+ g_free(err_msg);
return error_string;
}
}
diff --git a/epan/wslua/wslua_field.c b/epan/wslua/wslua_field.c
index 5fe0715bba..5e96f25c83 100644
--- a/epan/wslua/wslua_field.c
+++ b/epan/wslua/wslua_field.c
@@ -475,6 +475,7 @@ void lua_prime_all_fields(proto_tree* tree _U_) {
GString* fake_tap_filter = g_string_new("frame");
guint i;
static gboolean fake_tap = FALSE;
+ gchar *err_msg;
for(i=0; i < wanted_fields->len; i++) {
Field f = (Field)g_ptr_array_index(wanted_fields,i);
@@ -514,8 +515,9 @@ void lua_prime_all_fields(proto_tree* tree _U_) {
dfilter_free(wslua_dfilter);
wslua_dfilter = NULL;
}
- if (!dfilter_compile(fake_tap_filter->str, &wslua_dfilter)) {
- report_failure("while compiling dfilter for wslua: '%s'", fake_tap_filter->str);
+ if (!dfilter_compile(fake_tap_filter->str, &wslua_dfilter, &err_msg)) {
+ report_failure("while compiling dfilter \"%s\" for wslua: %s", fake_tap_filter->str, err_msg);
+ g_free(err_msg);
}
}
}
diff --git a/epan/wslua/wslua_gui.c b/epan/wslua/wslua_gui.c
index b73564eff9..34623dfd71 100644
--- a/epan/wslua/wslua_gui.c
+++ b/epan/wslua/wslua_gui.c
@@ -730,7 +730,7 @@ WSLUA_FUNCTION wslua_open_capture_file(lua_State* L) { /* Open and display a cap
const char* fname = luaL_checkstring(L,WSLUA_ARG_open_capture_file_FILENAME);
const char* filter = luaL_optstring(L,WSLUA_ARG_open_capture_file_FILTER,NULL);
- const char* error = NULL;
+ char* error = NULL;
if (!ops->open_file) {
WSLUA_ERROR(open_capture_file, "GUI not available");
@@ -740,9 +740,10 @@ WSLUA_FUNCTION wslua_open_capture_file(lua_State* L) { /* Open and display a cap
if (! ops->open_file(fname,filter,&error) ) {
lua_pushboolean(L,FALSE);
- if (error)
+ if (error) {
lua_pushstring(L,error);
- else
+ g_free(error);
+ } else
lua_pushnil(L);
return 2;