diff --git a/dftest.c b/dftest.c index ff0459d146..05a8a1597e 100644 --- a/dftest.c +++ b/dftest.c @@ -75,7 +75,7 @@ main(int argc, char **argv) char *expanded_text; dfilter_t *df; gchar *err_msg; - dfilter_loc_t err_loc; + df_error_t *df_err; cmdarg_err_init(dftest_cmdarg_err, dftest_cmdarg_err_cont); @@ -164,15 +164,15 @@ main(int argc, char **argv) printf("Filter: %s\n", expanded_text); /* Compile it */ - if (!dfilter_compile_real(expanded_text, &df, &err_msg, &err_loc, + if (!dfilter_compile_real(expanded_text, &df, &df_err, "dftest", TRUE, FALSE)) { - fprintf(stderr, "dftest: %s\n", err_msg); - if (err_loc.col_start >= 0) { + fprintf(stderr, "dftest: %s\n", df_err->msg); + if (df_err->loc.col_start >= 0) { fprintf(stderr, "\t%s\n", expanded_text); fputc('\t', stderr); - putloc(stderr, err_loc); + putloc(stderr, df_err->loc); } - g_free(err_msg); + dfilter_error_free(df_err); g_free(expanded_text); epan_cleanup(); exit(2); diff --git a/epan/color_filters.c b/epan/color_filters.c index 9efbdb22a2..75fda92d43 100644 --- a/epan/color_filters.c +++ b/epan/color_filters.c @@ -156,7 +156,7 @@ color_filters_set_tmp(guint8 filt_nr, const gchar *filter, gboolean disabled, gc color_filter_t *colorf; dfilter_t *compiled_filter; guint8 i; - gchar *local_err_msg = NULL; + df_error_t *df_err = NULL; /* Go through the temporary filters and look for the same filter string. * If found, clear it so that a filter can be "moved" up and down the list */ @@ -179,9 +179,9 @@ color_filters_set_tmp(guint8 filt_nr, const gchar *filter, gboolean disabled, gc * or if we found a matching filter string which need to be cleared */ tmpfilter = ( (filter==NULL) || (i!=filt_nr) ) ? "frame" : filter; - if (!dfilter_compile(tmpfilter, &compiled_filter, &local_err_msg)) { - *err_msg = ws_strdup_printf( "Could not compile color filter name: \"%s\" text: \"%s\".\n%s", name, filter, local_err_msg); - g_free(local_err_msg); + if (!dfilter_compile(tmpfilter, &compiled_filter, &df_err)) { + *err_msg = ws_strdup_printf( "Could not compile color filter name: \"%s\" text: \"%s\".\n%s", name, filter, df_err->msg); + dfilter_error_free(df_err); g_free(name); return FALSE; } else { @@ -405,17 +405,17 @@ color_filter_compile_cb(gpointer filter_arg, gpointer err) { color_filter_t *colorf = (color_filter_t *)filter_arg; gchar **err_msg = (gchar**)err; - gchar *local_err_msg = NULL; + df_error_t *df_err = NULL; ws_assert(colorf->c_colorfilter == NULL); /* If the filter is disabled it doesn't matter if it compiles or not. */ if (colorf->disabled) return; - if (!dfilter_compile(colorf->filter_text, &colorf->c_colorfilter, &local_err_msg)) { + if (!dfilter_compile(colorf->filter_text, &colorf->c_colorfilter, &df_err)) { *err_msg = ws_strdup_printf("Could not compile color filter name: \"%s\" text: \"%s\".\n%s", - colorf->filter_name, colorf->filter_text, local_err_msg); - g_free(local_err_msg); + colorf->filter_name, colorf->filter_text, df_err->msg); + dfilter_error_free(df_err); /* this filter was compilable before, so this should never happen */ /* except if the OK button of the parent window has been clicked */ /* so don't use ws_assert_not_reached() but check the filters again */ @@ -427,17 +427,17 @@ color_filter_validate_cb(gpointer filter_arg, gpointer err) { color_filter_t *colorf = (color_filter_t *)filter_arg; gchar **err_msg = (gchar**)err; - gchar *local_err_msg; + df_error_t *df_err = NULL; ws_assert(colorf->c_colorfilter == NULL); /* If the filter is disabled it doesn't matter if it compiles or not. */ if (colorf->disabled) return; - if (!dfilter_compile(colorf->filter_text, &colorf->c_colorfilter, &local_err_msg)) { + if (!dfilter_compile(colorf->filter_text, &colorf->c_colorfilter, &df_err)) { *err_msg = ws_strdup_printf("Disabling color filter name: \"%s\" filter: \"%s\".\n%s", - colorf->filter_name, colorf->filter_text, local_err_msg); - g_free(local_err_msg); + colorf->filter_name, colorf->filter_text, df_err->msg); + dfilter_error_free(df_err); /* Disable the color filter in the list of color filters. */ colorf->disabled = TRUE; @@ -651,12 +651,12 @@ read_filters_file(const gchar *path, FILE *f, gpointer user_data, color_filter_a color_t bg_color, fg_color; color_filter_t *colorf; dfilter_t *temp_dfilter = NULL; - gchar *local_err_msg = NULL; + df_error_t *df_err = NULL; - if (!disabled && !dfilter_compile(filter_exp, &temp_dfilter, &local_err_msg)) { + if (!disabled && !dfilter_compile(filter_exp, &temp_dfilter, &df_err)) { ws_warning("Could not compile \"%s\" in colorfilters file \"%s\".\n%s", - name, path, local_err_msg); - g_free(local_err_msg); + name, path, df_err->msg); + dfilter_error_free(df_err); prefs.unknown_colorfilters = TRUE; /* skip_end_of_line = TRUE; */ diff --git a/epan/dfilter/dfilter-int.h b/epan/dfilter/dfilter-int.h index ad38e368d6..7ad88f2280 100644 --- a/epan/dfilter/dfilter-int.h +++ b/epan/dfilter/dfilter-int.h @@ -43,8 +43,8 @@ struct epan_dfilter { typedef struct { /* Syntax Tree stuff */ stnode_t *st_root; - gboolean syntax_error; - gchar *error_message; + gboolean parse_failure; + df_error_t error; GPtrArray *insns; GHashTable *loaded_fields; GHashTable *loaded_raw_fields; @@ -55,7 +55,6 @@ typedef struct { GHashTable *references; /* hfinfo -> pointer to array of references */ GHashTable *raw_references; /* hfinfo -> pointer to array of references */ char *expanded_text; - stloc_t err_loc; } dfwork_t; /* @@ -80,17 +79,17 @@ void Dfilter(void*, int, stnode_t*, dfwork_t*); #define SCAN_FAILED -1 /* not 0, as that means end-of-input */ void -dfilter_vfail(dfwork_t *dfw, stloc_t *err_loc, +dfilter_vfail(dfwork_t *dfw, int code, stloc_t *err_loc, const char *format, va_list args); void -dfilter_fail(dfwork_t *dfw, stloc_t *err_loc, - const char *format, ...) G_GNUC_PRINTF(3, 4); +dfilter_fail(dfwork_t *dfw, int code, stloc_t *err_loc, + const char *format, ...) G_GNUC_PRINTF(4, 5); WS_NORETURN void -dfilter_fail_throw(dfwork_t *dfw, stloc_t *err_loc, - const char *format, ...) G_GNUC_PRINTF(3, 4); +dfilter_fail_throw(dfwork_t *dfw, int code, stloc_t *err_loc, + const char *format, ...) G_GNUC_PRINTF(4, 5); void dfw_set_error_location(dfwork_t *dfw, stloc_t *err_loc); @@ -126,4 +125,13 @@ reference_new(const field_info *finfo, gboolean raw); void reference_free(df_reference_t *ref); +void dfw_error_init(df_error_t *err); + +void dfw_error_clear(df_error_t *err); + +void dfw_error_set_msg(df_error_t **errp, const char *fmt, ...) +G_GNUC_PRINTF(2, 3); + +void dfw_error_take(df_error_t **errp, df_error_t *src); + #endif diff --git a/epan/dfilter/dfilter.c b/epan/dfilter/dfilter.c index 3466b04271..1e3d66570a 100644 --- a/epan/dfilter/dfilter.c +++ b/epan/dfilter/dfilter.c @@ -42,46 +42,44 @@ static void* ParserObj = NULL; dfwork_t *global_dfw; void -dfilter_vfail(dfwork_t *dfw, stloc_t *loc, +dfilter_vfail(dfwork_t *dfw, int code, stloc_t *loc, const char *format, va_list args) { - /* Flag a syntax error. This is currently only used in - * the grammar parsing stage to terminate the parsing - * loop. */ - dfw->syntax_error = TRUE; + dfw->parse_failure = TRUE; /* If we've already reported one error, don't overwite it */ - if (dfw->error_message != NULL) + if (dfw->error.code < 0 || dfw->error.msg != NULL) return; - dfw->error_message = ws_strdup_vprintf(format, args); + dfw->error.code = code; + dfw->error.msg = ws_strdup_vprintf(format, args); if (loc) { - dfw->err_loc = *loc; + dfw->error.loc = *(dfilter_loc_t *)loc; } else { - dfw->err_loc.col_start = -1; - dfw->err_loc.col_len = 0; + dfw->error.loc.col_start = -1; + dfw->error.loc.col_len = 0; } } void -dfilter_fail(dfwork_t *dfw, stloc_t *loc, +dfilter_fail(dfwork_t *dfw, int code, stloc_t *loc, const char *format, ...) { va_list args; va_start(args, format); - dfilter_vfail(dfw, loc, format, args); + dfilter_vfail(dfw, code, loc, format, args); va_end(args); } void -dfilter_fail_throw(dfwork_t *dfw, stloc_t *loc, const char *format, ...) +dfilter_fail_throw(dfwork_t *dfw, int code, stloc_t *loc, const char *format, ...) { va_list args; va_start(args, format); - dfilter_vfail(dfw, loc, format, args); + dfilter_vfail(dfw, code, loc, format, args); va_end(args); THROW(TypeError); } @@ -91,7 +89,7 @@ dfw_set_error_location(dfwork_t *dfw, stloc_t *loc) { /* Set new location. */ ws_assert(loc); - dfw->err_loc = *loc; + dfw->error.loc = *(dfilter_loc_t *)loc; } header_field_info * @@ -232,6 +230,8 @@ dfwork_new(void) { dfwork_t *dfw = g_new0(dfwork_t, 1); + dfw_error_init(&dfw->error); + dfw->references = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)free_refs_array); @@ -355,7 +355,7 @@ dfilter_expand(const char *expr, char **err_ret) gboolean dfilter_compile_real(const gchar *text, dfilter_t **dfp, - gchar **error_ret, dfilter_loc_t *loc_ptr, + df_error_t **errpp, const char *caller, gboolean save_tree, gboolean apply_macros) { @@ -376,10 +376,8 @@ dfilter_compile_real(const gchar *text, dfilter_t **dfp, ws_log(WS_LOG_DOMAIN, LOG_LEVEL_DEBUG, "%s() called from %s() with null filter", __func__, caller); - if (error_ret != NULL) { - /* XXX This BUG happens often. Some callers are ignoring these errors. */ - *error_ret = g_strdup("BUG: NULL text pointer passed to dfilter_compile"); - } + /* XXX This BUG happens often. Some callers are ignoring these errors. */ + dfw_error_set_msg(errpp, "BUG: NULL text pointer passed to dfilter_compile"); return FALSE; } else if (*text == '\0') { @@ -397,7 +395,7 @@ dfilter_compile_real(const gchar *text, dfilter_t **dfp, dfw = dfwork_new(); if (apply_macros) { - dfw->expanded_text = dfilter_macro_apply(text, &dfw->error_message); + dfw->expanded_text = dfilter_macro_apply(text, &dfw->error.msg); if (dfw->expanded_text == NULL) { goto FAILURE; } @@ -409,7 +407,7 @@ dfilter_compile_real(const gchar *text, dfilter_t **dfp, } if (df_lex_init(&scanner) != 0) { - dfw->error_message = ws_strdup_printf("Can't initialize scanner: %s", g_strerror(errno)); + dfw_error_set_msg(errpp, "Can't initialize scanner: %s", g_strerror(errno)); goto FAILURE; } @@ -444,7 +442,7 @@ dfilter_compile_real(const gchar *text, dfilter_t **dfp, /* The parser has freed the lval for us. */ df_lval = NULL; - if (dfw->syntax_error) { + if (dfw->parse_failure) { failure = TRUE; break; } @@ -467,7 +465,7 @@ dfilter_compile_real(const gchar *text, dfilter_t **dfp, Dfilter(ParserObj, 0, NULL, dfw); /* One last check for syntax error (after EOF) */ - if (dfw->syntax_error) + if (dfw->parse_failure) failure = TRUE; /* Free scanner state */ @@ -547,22 +545,13 @@ dfilter_compile_real(const gchar *text, dfilter_t **dfp, FAILURE: ws_assert(dfw); - if (dfw->error_message == NULL) { + if (dfw->error.msg == NULL) { /* We require an error message. */ ws_critical("Unknown error compiling filter: %s", text); } else { - ws_debug("Compiling filter failed with error: %s.", dfw->error_message); - if (error_ret != NULL) { - *error_ret = dfw->error_message; - } - else { - g_free(dfw->error_message); - } - if (loc_ptr != NULL) { - loc_ptr->col_start = dfw->err_loc.col_start; - loc_ptr->col_len = dfw->err_loc.col_len; - } + ws_debug("Compiling filter failed with error: %s.", dfw->error.msg); + dfw_error_take(errpp, &dfw->error); } global_dfw = NULL; @@ -738,6 +727,63 @@ reference_free(df_reference_t *ref) g_free(ref); } +void +dfw_error_init(df_error_t *err) { + err->code = 0; + err->msg = NULL; + err->loc.col_start = -1; + err->loc.col_len = 0; +} + +void +dfw_error_clear(df_error_t *err) { + g_free(err->msg); + dfw_error_init(err); +} + +void +dfw_error_set_msg(df_error_t **errpp, const char *fmt, ...) +{ + if (errpp == NULL) { + return; + } + va_list ap; + + df_error_t *errp = g_new(df_error_t, 1); + errp->code = DF_ERROR_GENERIC; + va_start(ap, fmt); + errp->msg = ws_strdup_vprintf(fmt, ap); + va_end(ap); + errp->loc.col_start = -1; + errp->loc.col_len = 0; + *errpp = errp; +} + +void +dfw_error_take(df_error_t **errpp, df_error_t *src) +{ + if (errpp == NULL) { + g_free(src->msg); + dfw_error_init(src); + return; + } + df_error_t *errp = g_new(df_error_t, 1); + errp->code = src->code; + errp->msg = src->msg; + errp->loc = src->loc; + *errpp = errp; + dfw_error_init(src); +} + +void +dfilter_error_free(df_error_t *errp) +{ + if (errp == NULL) + return; + g_free(errp->msg); + g_free(errp); +} + /* * Editor modelines - https://www.wireshark.org/tools/modelines.html * diff --git a/epan/dfilter/dfilter.h b/epan/dfilter/dfilter.h index 7a4499de1d..0d03976364 100644 --- a/epan/dfilter/dfilter.h +++ b/epan/dfilter/dfilter.h @@ -52,23 +52,32 @@ dfilter_expand(const char *expr, char **err_ret); * Returns TRUE on success, FALSE on failure. */ +#define DF_ERROR_GENERIC -1 + typedef struct _dfilter_loc { long col_start; size_t col_len; } dfilter_loc_t; +typedef struct { + int code; + char *msg; + dfilter_loc_t loc; +} df_error_t; + +WS_DLL_PUBLIC +void +dfilter_error_free(df_error_t *); + WS_DLL_PUBLIC gboolean dfilter_compile_real(const gchar *text, dfilter_t **dfp, - gchar **err_msg, dfilter_loc_t *loc_ptr, + df_error_t **errpp, const char *caller, gboolean save_tree, gboolean apply_macros); -#define dfilter_compile(text, dfp, err_msg) \ - dfilter_compile_real(text, dfp, err_msg, NULL, __func__, FALSE, TRUE) - -#define dfilter_compile2(text, dfp, err_msg, loc_ptr) \ - dfilter_compile_real(text, dfp, err_msg, loc_ptr, __func__, FALSE, TRUE) +#define dfilter_compile(text, dfp, errp) \ + dfilter_compile_real(text, dfp, errp, __func__, FALSE, TRUE) /* Frees all memory used by dfilter, and frees * the dfilter itself. */ diff --git a/epan/dfilter/dfunctions.c b/epan/dfilter/dfunctions.c index 689d9dbe45..1ceaa25df4 100644 --- a/epan/dfilter/dfunctions.c +++ b/epan/dfilter/dfunctions.c @@ -22,7 +22,7 @@ #include #define FAIL(dfw, node, ...) \ - dfilter_fail_throw(dfw, stnode_location(node), __VA_ARGS__) + dfilter_fail_throw(dfw, DF_ERROR_GENERIC, stnode_location(node), __VA_ARGS__) /* Convert an FT_STRING using a callback function */ static gboolean diff --git a/epan/dfilter/grammar.lemon b/epan/dfilter/grammar.lemon index d6caa0d927..5b841fa90f 100644 --- a/epan/dfilter/grammar.lemon +++ b/epan/dfilter/grammar.lemon @@ -22,7 +22,7 @@ static stnode_t * new_function(dfwork_t *dfw, stnode_t *node); -#define FAIL(dfw, node, ...) dfilter_fail(dfw, stnode_location(node), __VA_ARGS__) +#define FAIL(dfw, node, ...) dfilter_fail(dfw, DF_ERROR_GENERIC, stnode_location(node), __VA_ARGS__) DIAG_OFF_LEMON() } /* end of %include */ @@ -65,7 +65,7 @@ DIAG_ON_LEMON() any "error" symbols are shifted, if possible. */ %syntax_error { if (!TOKEN) { - dfilter_fail(dfw, NULL, "Unexpected end of filter expression."); + dfilter_fail(dfw, DF_ERROR_GENERIC, NULL, "Unexpected end of filter expression."); return; } FAIL(dfw, TOKEN, "\"%s\" was unexpected in this context.", stnode_token(TOKEN)); @@ -76,7 +76,7 @@ the above syntax_error code and after the parser fails to use error recovery, shifting an "error" symbol and successfully shifting 3 more symbols. */ %parse_failure { - dfw->syntax_error = TRUE; + dfw->parse_failure = TRUE; } /* ----------------- The grammar -------------- */ diff --git a/epan/dfilter/scanner.l b/epan/dfilter/scanner.l index b90f1a28b3..0b54689a3b 100644 --- a/epan/dfilter/scanner.l +++ b/epan/dfilter/scanner.l @@ -97,7 +97,7 @@ static gboolean parse_charconst(df_scanner_state_t *state, const char *s, unsign static void update_location(df_scanner_state_t *state, const char *text); static void update_string_loc(df_scanner_state_t *state, const char *text); -#define FAIL(...) dfilter_fail(yyextra->dfw, &yyextra->location, __VA_ARGS__) +#define FAIL(...) dfilter_fail(yyextra->dfw, DF_ERROR_GENERIC, &yyextra->location, __VA_ARGS__) /* * Sleazy hack to suppress compiler warnings in yy_fatal_error(). @@ -551,7 +551,7 @@ set_lval_field(df_scanner_state_t *state, const char *token_value) hfinfo = dfilter_resolve_unparsed(state->dfw, token_value); if (hfinfo == NULL) { - dfilter_fail(state->dfw, &state->location, "\"%s\" is not a valid protocol or protocol field.", token_value); + dfilter_fail(state->dfw, DF_ERROR_GENERIC, &state->location, "\"%s\" is not a valid protocol or protocol field.", token_value); } stnode_init(df_lval, STTYPE_FIELD, hfinfo, g_strdup(token_value), &state->location); return TOKEN_FIELD; @@ -587,7 +587,7 @@ append_escaped_char(df_scanner_state_t *state, GString *str, char c) case '\"': break; default: - dfilter_fail(state->dfw, &state->location, + dfilter_fail(state->dfw, DF_ERROR_GENERIC, &state->location, "\\%c is not a valid character escape sequence", c); return FALSE; } @@ -657,7 +657,7 @@ append_universal_character_name(df_scanner_state_t *state, GString *str, const c gunichar val; if (!parse_universal_character_name(state, ucn, NULL, &val)) { - dfilter_fail(state->dfw, &state->location, "%s is not a valid universal character name", ucn); + dfilter_fail(state->dfw, DF_ERROR_GENERIC, &state->location, "%s is not a valid universal character name", ucn); return FALSE; } @@ -675,7 +675,7 @@ parse_charconst(df_scanner_state_t *state, const char *s, unsigned long *valuep) cp = s + 1; /* skip the leading ' */ if (*cp == '\'') { - dfilter_fail(state->dfw, &state->string_loc, "Empty character constant."); + dfilter_fail(state->dfw, DF_ERROR_GENERIC, &state->string_loc, "Empty character constant."); return FALSE; } @@ -691,7 +691,7 @@ parse_charconst(df_scanner_state_t *state, const char *s, unsigned long *valuep) switch (*cp) { case '\0': - dfilter_fail(state->dfw, &state->string_loc, "%s isn't a valid character constant.", s); + dfilter_fail(state->dfw, DF_ERROR_GENERIC, &state->string_loc, "%s isn't a valid character constant.", s); return FALSE; case 'a': @@ -752,7 +752,7 @@ parse_charconst(df_scanner_state_t *state, const char *s, unsigned long *valuep) else if (*cp >= 'a' && *cp <= 'f') value = 10 + (*cp - 'a'); else { - dfilter_fail(state->dfw, &state->string_loc, "%s isn't a valid character constant.", s); + dfilter_fail(state->dfw, DF_ERROR_GENERIC, &state->string_loc, "%s isn't a valid character constant.", s); return FALSE; } cp++; @@ -765,7 +765,7 @@ parse_charconst(df_scanner_state_t *state, const char *s, unsigned long *valuep) else if (*cp >= 'a' && *cp <= 'f') value |= 10 + (*cp - 'a'); else { - dfilter_fail(state->dfw, &state->string_loc, "%s isn't a valid character constant.", s); + dfilter_fail(state->dfw, DF_ERROR_GENERIC, &state->string_loc, "%s isn't a valid character constant.", s); return FALSE; } } @@ -775,7 +775,7 @@ parse_charconst(df_scanner_state_t *state, const char *s, unsigned long *valuep) case 'u': case 'U': if (!parse_universal_character_name(state, s+1, &endptr, &unival)) { - dfilter_fail(state->dfw, &state->string_loc, "%s is not a valid universal character name", s); + dfilter_fail(state->dfw, DF_ERROR_GENERIC, &state->string_loc, "%s is not a valid universal character name", s); return FALSE; } value = (unsigned long)unival; @@ -787,7 +787,7 @@ parse_charconst(df_scanner_state_t *state, const char *s, unsigned long *valuep) if (*cp >= '0' && *cp <= '7') value = *cp - '0'; else { - dfilter_fail(state->dfw, &state->string_loc, "%s isn't a valid character constant.", s); + dfilter_fail(state->dfw, DF_ERROR_GENERIC, &state->string_loc, "%s isn't a valid character constant.", s); return FALSE; } if (*(cp + 1) != '\'') { @@ -796,7 +796,7 @@ parse_charconst(df_scanner_state_t *state, const char *s, unsigned long *valuep) if (*cp >= '0' && *cp <= '7') value |= *cp - '0'; else { - dfilter_fail(state->dfw, &state->string_loc, "%s isn't a valid character constant.", s); + dfilter_fail(state->dfw, DF_ERROR_GENERIC, &state->string_loc, "%s isn't a valid character constant.", s); return FALSE; } if (*(cp + 1) != '\'') { @@ -805,13 +805,13 @@ parse_charconst(df_scanner_state_t *state, const char *s, unsigned long *valuep) if (*cp >= '0' && *cp <= '7') value |= *cp - '0'; else { - dfilter_fail(state->dfw, &state->string_loc, "%s isn't a valid character constant.", s); + dfilter_fail(state->dfw, DF_ERROR_GENERIC, &state->string_loc, "%s isn't a valid character constant.", s); return FALSE; } } } if (value > 0xFF) { - dfilter_fail(state->dfw, &state->string_loc, "%s is too large to be a valid character constant.", s); + dfilter_fail(state->dfw, DF_ERROR_GENERIC, &state->string_loc, "%s is too large to be a valid character constant.", s); return FALSE; } cp++; @@ -819,13 +819,13 @@ parse_charconst(df_scanner_state_t *state, const char *s, unsigned long *valuep) } else { value = *cp++; if (!g_ascii_isprint(value)) { - dfilter_fail(state->dfw, &state->string_loc, "Non-printable value '0x%02lx' in character constant.", value); + dfilter_fail(state->dfw, DF_ERROR_GENERIC, &state->string_loc, "Non-printable value '0x%02lx' in character constant.", value); return FALSE; } } if ((*cp != '\'') || (*(cp + 1) != '\0')){ - dfilter_fail(state->dfw, &state->string_loc, "%s is too long to be a valid character constant.", s); + dfilter_fail(state->dfw, DF_ERROR_GENERIC, &state->string_loc, "%s is too long to be a valid character constant.", s); return FALSE; } diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c index 6f0c28e704..a4d9d51595 100644 --- a/epan/dfilter/semcheck.c +++ b/epan/dfilter/semcheck.c @@ -34,7 +34,7 @@ #define FAIL(dfw, node, ...) \ do { \ ws_noisy("Semantic check failed here."); \ - dfilter_fail_throw(dfw, stnode_location(node), __VA_ARGS__); \ + dfilter_fail_throw(dfw, DF_ERROR_GENERIC, stnode_location(node), __VA_ARGS__); \ } while (0) static void @@ -151,6 +151,18 @@ node_is_constant(stnode_t *node) return FALSE; } +/* Don't set the error message if it's already set. */ +#define SET_ERROR(dfw, str) \ + do { \ + if ((str) != NULL && (dfw)->error.msg == NULL) { \ + (dfw)->error.msg = str; \ + (dfw)->error.code = DF_ERROR_GENERIC; \ + } \ + else { \ + g_free(str); \ + } \ + } while (0) + /* Gets an fvalue from a string, and sets the error message on failure. */ WS_RETNONNULL fvalue_t* @@ -159,10 +171,11 @@ dfilter_fvalue_from_literal(dfwork_t *dfw, ftenum_t ftype, stnode_t *st, { fvalue_t *fv; const char *s = stnode_data(st); + gchar *error_message = NULL; + + fv = fvalue_from_literal(ftype, s, allow_partial_value, &error_message); + SET_ERROR(dfw, error_message); - /* Don't set the error message if it's already set. */ - fv = fvalue_from_literal(ftype, s, allow_partial_value, - dfw->error_message == NULL ? &dfw->error_message : NULL); if (fv == NULL && hfinfo_value_string) { /* check value_string */ fv = mk_fvalue_from_val_string(dfw, hfinfo_value_string, s); @@ -170,9 +183,8 @@ dfilter_fvalue_from_literal(dfwork_t *dfw, ftenum_t ftype, stnode_t *st, * Ignore previous errors if this can be mapped * to an item from value_string. */ - if (fv && dfw->error_message) { - g_free(dfw->error_message); - dfw->error_message = NULL; + if (fv) { + dfw_error_clear(&dfw->error); } } if (fv == NULL) { @@ -191,18 +203,19 @@ dfilter_fvalue_from_string(dfwork_t *dfw, ftenum_t ftype, stnode_t *st, { fvalue_t *fv; const GString *gs = stnode_string(st); + gchar *error_message = NULL; + + fv = fvalue_from_string(ftype, gs->str, gs->len, &error_message); + SET_ERROR(dfw, error_message); - fv = fvalue_from_string(ftype, gs->str, gs->len, - dfw->error_message == NULL ? &dfw->error_message : NULL); if (fv == NULL && hfinfo_value_string) { fv = mk_fvalue_from_val_string(dfw, hfinfo_value_string, gs->str); /* * Ignore previous errors if this can be mapped * to an item from value_string. */ - if (fv && dfw->error_message) { - g_free(dfw->error_message); - dfw->error_message = NULL; + if (fv) { + dfw_error_clear(&dfw->error); } } if (fv == NULL) { @@ -319,9 +332,8 @@ mk_fvalue_from_val_string(dfwork_t *dfw, header_field_info *hfinfo, const char * * Prefer this error message to whatever error message * has already been set. */ - g_free(dfw->error_message); - dfw->error_message = NULL; - dfilter_fail(dfw, NULL, "\"%s\" cannot be found among the possible values for %s.", + dfw_error_clear(&dfw->error); + dfilter_fail(dfw, DF_ERROR_GENERIC, NULL, "\"%s\" cannot be found among the possible values for %s.", s, hfinfo->abbrev); return NULL; } @@ -329,7 +341,7 @@ mk_fvalue_from_val_string(dfwork_t *dfw, header_field_info *hfinfo, const char * /* Do val_strings exist? */ if (!hfinfo->strings) { - dfilter_fail(dfw, NULL, "%s cannot accept strings as values.", + dfilter_fail(dfw, DF_ERROR_GENERIC, NULL, "%s cannot accept strings as values.", hfinfo->abbrev); return NULL; } @@ -337,11 +349,10 @@ mk_fvalue_from_val_string(dfwork_t *dfw, header_field_info *hfinfo, const char * /* 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; + dfw_error_clear(&dfw->error); if (hfinfo->display & BASE_RANGE_STRING) { - dfilter_fail(dfw, NULL, "\"%s\" cannot accept [range] strings as values.", + dfilter_fail(dfw, DF_ERROR_GENERIC, NULL, "\"%s\" cannot accept [range] strings as values.", hfinfo->abbrev); } else if (hfinfo->display & BASE_VAL64_STRING) { @@ -353,7 +364,7 @@ mk_fvalue_from_val_string(dfwork_t *dfw, header_field_info *hfinfo, const char * } vals++; } - dfilter_fail(dfw, NULL, "\"%s\" cannot be found among the possible values for %s.", + dfilter_fail(dfw, DF_ERROR_GENERIC, NULL, "\"%s\" cannot be found among the possible values for %s.", s, hfinfo->abbrev); } else if (hfinfo->display == BASE_CUSTOM) { @@ -363,7 +374,7 @@ mk_fvalue_from_val_string(dfwork_t *dfw, header_field_info *hfinfo, const char * * integer, we have the string they're trying to match. * -><- */ - dfilter_fail(dfw, NULL, "\"%s\" cannot accept [custom] strings as values.", + dfilter_fail(dfw, DF_ERROR_GENERIC, NULL, "\"%s\" cannot accept [custom] strings as values.", hfinfo->abbrev); } else { @@ -377,7 +388,7 @@ mk_fvalue_from_val_string(dfwork_t *dfw, header_field_info *hfinfo, const char * } vals++; } - dfilter_fail(dfw, NULL, "\"%s\" cannot be found among the possible values for %s.", + dfilter_fail(dfw, DF_ERROR_GENERIC, NULL, "\"%s\" cannot be found among the possible values for %s.", s, hfinfo->abbrev); } return NULL; @@ -567,9 +578,10 @@ dfilter_fvalue_from_charconst(dfwork_t *dfw, ftenum_t ftype, stnode_t *st) { fvalue_t *fvalue; unsigned long *nump = stnode_data(st); + char *error_message = NULL; - fvalue = fvalue_from_charconst(ftype, *nump, - dfw->error_message == NULL ? &dfw->error_message : NULL); + fvalue = fvalue_from_charconst(ftype, *nump, &error_message); + SET_ERROR(dfw, error_message); if (fvalue == NULL) { dfw_set_error_location(dfw, stnode_location(st)); @@ -980,7 +992,7 @@ check_relation_matches(dfwork_t *dfw, stnode_t *st_node, pcre = ws_regex_compile_ex(patt->str, patt->len, &errmsg, WS_REGEX_CASELESS|WS_REGEX_NEVER_UTF); if (errmsg) { - dfilter_fail(dfw, NULL, "Regex compilation error: %s.", errmsg); + dfilter_fail(dfw, DF_ERROR_GENERIC, NULL, "Regex compilation error: %s.", errmsg); g_free(errmsg); THROW(TypeError); } @@ -1177,7 +1189,7 @@ check_arithmetic_expr(dfwork_t *dfw, stnode_t *st_node, ftenum_t lhs_ftype) char *err_msg; fvalue_t *new_fv = fvalue_unary_minus(stnode_data(st_arg1), &err_msg); if (new_fv == NULL) { - dfilter_fail(dfw, stnode_location(st_arg1), + dfilter_fail(dfw, DF_ERROR_GENERIC, stnode_location(st_arg1), "%s: %s", stnode_todisplay(st_arg1), err_msg); g_free(err_msg); THROW(TypeError); diff --git a/epan/dissectors/packet-ncp2222.inc b/epan/dissectors/packet-ncp2222.inc index 7659fc683f..4df2d024e5 100644 --- a/epan/dissectors/packet-ncp2222.inc +++ b/epan/dissectors/packet-ncp2222.inc @@ -7077,14 +7077,14 @@ static void ncp2222_compile_dfilters(void) { int i; - gchar *err_msg; + df_error_t *df_err; for (i = 0; i < NUM_REQ_CONDS; i++) { if (!dfilter_compile((const gchar*)req_conds[i].dfilter_text, - &req_conds[i].dfilter, &err_msg)) { + &req_conds[i].dfilter, &df_err)) { g_error("NCP dissector failed to compile dfilter \"%s\": %s\n", - req_conds[i].dfilter_text, err_msg); - g_free(err_msg); + req_conds[i].dfilter_text, df_err->msg); + dfilter_error_free(df_err); ws_assert_not_reached(); } } diff --git a/epan/tap.c b/epan/tap.c index 9fee740ba1..da0b378d44 100644 --- a/epan/tap.c +++ b/epan/tap.c @@ -541,7 +541,7 @@ register_tap_listener(const char *tapname, void *tapdata, const char *fstring, int tap_id; dfilter_t *code=NULL; GString *error_string; - gchar *err_msg; + df_error_t *df_err; tap_id=find_tap_id(tapname); if(!tap_id){ @@ -555,12 +555,12 @@ register_tap_listener(const char *tapname, void *tapdata, const char *fstring, tl->failed=FALSE; tl->flags=flags; if(fstring){ - if(!dfilter_compile(fstring, &code, &err_msg)){ + if(!dfilter_compile(fstring, &code, &df_err)){ error_string = g_string_new(""); g_string_printf(error_string, "Filter \"%s\" is invalid - %s", - fstring, err_msg); - g_free(err_msg); + fstring, df_err->msg); + dfilter_error_free(df_err); free_tap_listener(tl); return error_string; } @@ -589,7 +589,7 @@ set_tap_dfilter(void *tapdata, const char *fstring) tap_listener_t *tl=NULL,*tl2; dfilter_t *code=NULL; GString *error_string; - gchar *err_msg; + df_error_t *df_err; if(!tap_listener_queue){ return NULL; @@ -615,13 +615,13 @@ set_tap_dfilter(void *tapdata, const char *fstring) tl->needs_redraw=TRUE; g_free(tl->fstring); if(fstring){ - if(!dfilter_compile(fstring, &code, &err_msg)){ + if(!dfilter_compile(fstring, &code, &df_err)){ tl->fstring=NULL; error_string = g_string_new(""); g_string_printf(error_string, "Filter \"%s\" is invalid - %s", - fstring, err_msg); - g_free(err_msg); + fstring, df_err->msg); + dfilter_error_free(df_err); return error_string; } } @@ -639,7 +639,6 @@ tap_listeners_dfilter_recompile(void) { tap_listener_t *tl; dfilter_t *code; - gchar *err_msg; for(tl=tap_listener_queue;tl;tl=tl->next){ if(tl->code){ @@ -649,12 +648,9 @@ tap_listeners_dfilter_recompile(void) tl->needs_redraw=TRUE; code=NULL; if(tl->fstring){ - if(!dfilter_compile(tl->fstring, &code, &err_msg)){ - g_free(err_msg); - err_msg = NULL; + if(!dfilter_compile(tl->fstring, &code, NULL)){ /* Not valid, make a dfilter matching no packets */ - if (!dfilter_compile("frame.number == 0", &code, &err_msg)) - g_free(err_msg); + dfilter_compile("frame.number == 0", &code, NULL); } } tl->code=code; diff --git a/epan/wslua/wslua_field.c b/epan/wslua/wslua_field.c index eb71179f28..13d9bc5791 100644 --- a/epan/wslua/wslua_field.c +++ b/epan/wslua/wslua_field.c @@ -556,7 +556,7 @@ static gboolean fake_tap = FALSE; void lua_prime_all_fields(proto_tree* tree _U_) { GString* fake_tap_filter = g_string_new("frame"); guint i; - gchar *err_msg; + df_error_t *df_err; for(i=0; i < wanted_fields->len; i++) { Field f = (Field)g_ptr_array_index(wanted_fields,i); @@ -585,9 +585,9 @@ void lua_prime_all_fields(proto_tree* tree _U_) { if (error) { report_failure("while registering lua_fake_tap:\n%s",error->str); g_string_free(error,TRUE); - } else 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); + } else if (!dfilter_compile(fake_tap_filter->str, &wslua_dfilter, &df_err)) { + report_failure("while compiling dfilter \"%s\" for wslua: %s", fake_tap_filter->str, df_err->msg); + dfilter_error_free(df_err); } } g_string_free(fake_tap_filter, TRUE); diff --git a/file.c b/file.c index 49db838580..96e4e4bdfc 100644 --- a/file.c +++ b/file.c @@ -1475,7 +1475,7 @@ cf_filter_packets(capture_file *cf, gchar *dftext, gboolean force) const char *filter_new = dftext ? dftext : ""; const char *filter_old = cf->dfilter ? cf->dfilter : ""; dfilter_t *dfcode; - gchar *err_msg; + df_error_t *df_err; /* if new filter equals old one, do nothing unless told to do so */ if (!force && strcmp(filter_new, filter_old) == 0) { @@ -1494,13 +1494,13 @@ cf_filter_packets(capture_file *cf, gchar *dftext, gboolean force) * and try to compile it. */ dftext = g_strdup(dftext); - if (!dfilter_compile(dftext, &dfcode, &err_msg)) { + if (!dfilter_compile(dftext, &dfcode, &df_err)) { /* The attempt failed; report an error. */ simple_message_box(ESD_TYPE_ERROR, NULL, "See the help for a description of the display filter syntax.", "\"%s\" isn't a valid display filter: %s", - dftext, err_msg); - g_free(err_msg); + dftext, df_err->msg); + dfilter_error_free(df_err); g_free(dftext); return CF_ERROR; } diff --git a/rawshark.c b/rawshark.c index 99ca32c556..ed4fa4b9a4 100644 --- a/rawshark.c +++ b/rawshark.c @@ -398,6 +398,7 @@ main(int argc, char *argv[]) { char *err_msg; int opt, i; + df_error_t *df_err; #ifndef _WIN32 struct rlimit limit; @@ -759,9 +760,9 @@ main(int argc, char *argv[]) if (n_rfilters != 0) { for (i = 0; i < n_rfilters; i++) { - if (!dfilter_compile(rfilters[i], &rfcodes[n_rfcodes], &err_msg)) { - cmdarg_err("%s", err_msg); - g_free(err_msg); + if (!dfilter_compile(rfilters[i], &rfcodes[n_rfcodes], &df_err)) { + cmdarg_err("%s", df_err->msg); + dfilter_error_free(df_err); ret = INVALID_DFILTER; goto clean_exit; } diff --git a/sharkd.c b/sharkd.c index 209638dd66..f057a66513 100644 --- a/sharkd.c +++ b/sharkd.c @@ -646,8 +646,7 @@ sharkd_filter(const char *dftext, guint8 **result) epan_dissect_t edt; - if (!dfilter_compile(dftext, &dfcode, &err_info)) { - g_free(err_info); + if (!dfilter_compile(dftext, &dfcode, NULL)) { return -1; } diff --git a/sharkd_session.c b/sharkd_session.c index 947f1c66cd..b34ab30f84 100644 --- a/sharkd_session.c +++ b/sharkd_session.c @@ -4069,26 +4069,27 @@ sharkd_session_process_check(char *buf, const jsmntok_t *tokens, int count) if (tok_filter != NULL) { - char *err_msg = NULL; dfilter_t *dfp; + df_error_t *df_err = NULL; - if (dfilter_compile(tok_filter, &dfp, &err_msg)) + if (dfilter_compile(tok_filter, &dfp, &df_err)) { if (dfp && dfilter_deprecated_tokens(dfp)) - sharkd_json_warning(rpcid, err_msg); + sharkd_json_warning(rpcid, df_err->msg); else sharkd_json_simple_ok(rpcid); dfilter_free(dfp); - g_free(err_msg); + dfilter_error_free(df_err); return 0; } else { sharkd_json_error( rpcid, -5001, NULL, - "Filter invalid - %s", err_msg + "Filter invalid - %s", df_err->msg ); + dfilter_error_free(df_err); return -5001; } } diff --git a/tfshark.c b/tfshark.c index 7f5db84cc9..aaa52951ca 100644 --- a/tfshark.c +++ b/tfshark.c @@ -282,7 +282,7 @@ main(int argc, char *argv[]) gchar *dfilter = NULL; dfilter_t *rfcode = NULL; dfilter_t *dfcode = NULL; - gchar *err_msg; + df_error_t *df_err; e_prefs *prefs_p; gchar *output_only = NULL; @@ -859,9 +859,9 @@ main(int argc, char *argv[]) build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE); if (rfilter != NULL) { - if (!dfilter_compile(rfilter, &rfcode, &err_msg)) { - cmdarg_err("%s", err_msg); - g_free(err_msg); + if (!dfilter_compile(rfilter, &rfcode, &df_err)) { + cmdarg_err("%s", df_err->msg); + dfilter_error_free(df_err); exit_status = INVALID_FILTER; goto clean_exit; } @@ -869,9 +869,9 @@ main(int argc, char *argv[]) cfile.rfcode = rfcode; if (dfilter != NULL) { - if (!dfilter_compile(dfilter, &dfcode, &err_msg)) { - cmdarg_err("%s", err_msg); - g_free(err_msg); + if (!dfilter_compile(dfilter, &dfcode, &df_err)) { + cmdarg_err("%s", df_err->msg); + dfilter_error_free(df_err); exit_status = INVALID_FILTER; goto clean_exit; } diff --git a/tshark.c b/tshark.c index 066491fb50..f00ba45ea1 100644 --- a/tshark.c +++ b/tshark.c @@ -614,8 +614,8 @@ static gboolean _compile_dfilter(const char *text, dfilter_t **dfp, const char *caller) { gboolean ok; - dfilter_loc_t err_loc; char *err_msg = NULL; + df_error_t *df_err; char *err_off; char *expanded; @@ -626,16 +626,17 @@ _compile_dfilter(const char *text, dfilter_t **dfp, const char *caller) return FALSE; } - ok = dfilter_compile_real(expanded, dfp, &err_msg, &err_loc, caller, FALSE, FALSE); + ok = dfilter_compile_real(expanded, dfp, &df_err, caller, FALSE, FALSE); if (!ok ) { - cmdarg_err("%s", err_msg); - g_free(err_msg); - if (err_loc.col_start >= 0) { - err_off = ws_strdup_underline(NULL, err_loc.col_start, err_loc.col_len); + cmdarg_err("%s", df_err->msg); + + if (df_err->loc.col_start >= 0) { + err_off = ws_strdup_underline(NULL, df_err->loc.col_start, df_err->loc.col_len); cmdarg_err_cont(" %s", expanded); cmdarg_err_cont(" %s", err_off); g_free(err_off); } + dfilter_error_free(df_err); } g_free(expanded); diff --git a/ui/logray/logray_main.cpp b/ui/logray/logray_main.cpp index db2a044614..774840593c 100644 --- a/ui/logray/logray_main.cpp +++ b/ui/logray/logray_main.cpp @@ -428,6 +428,7 @@ int main(int argc, char *qt_argv[]) #endif #endif gchar *err_msg = NULL; + df_error_t *df_err = NULL; QString dfilter, read_filter; #ifdef HAVE_LIBPCAP @@ -960,13 +961,13 @@ int main(int argc, char *qt_argv[]) } else if (global_commandline_info.jfilter != NULL) { dfilter_t *jump_to_filter = NULL; /* try to compile given filter */ - if (!dfilter_compile(global_commandline_info.jfilter, &jump_to_filter, &err_msg)) { + if (!dfilter_compile(global_commandline_info.jfilter, &jump_to_filter, &df_err)) { // Similar code in MainWindow::mergeCaptureFile(). QMessageBox::warning(main_w, QObject::tr("Invalid Display Filter"), QObject::tr("The filter expression %1 isn't a valid display filter. (%2).") - .arg(global_commandline_info.jfilter, err_msg), + .arg(global_commandline_info.jfilter, df_err->msg), QMessageBox::Ok); - g_free(err_msg); + dfilter_error_free(df_err); } else { /* Filter ok, jump to the first packet matching the filter conditions. Default search direction is forward, but if diff --git a/ui/logray/logray_main_window.cpp b/ui/logray/logray_main_window.cpp index 6c1dd3973a..8151f07b27 100644 --- a/ui/logray/logray_main_window.cpp +++ b/ui/logray/logray_main_window.cpp @@ -1164,16 +1164,16 @@ void LograyMainWindow::mergeCaptureFile() char *tmpname; if (merge_dlg.merge(file_name, read_filter)) { - gchar *err_msg; + df_error_t *df_err = NULL; - if (!dfilter_compile(qUtf8Printable(read_filter), &rfcode, &err_msg)) { + if (!dfilter_compile(qUtf8Printable(read_filter), &rfcode, &df_err)) { /* Not valid. Tell the user, and go back and run the file selection box again once they dismiss the alert. */ // Similar to commandline_info.jfilter section in main(). QMessageBox::warning(this, tr("Invalid Read Filter"), - QString(tr("The filter expression %1 isn't a valid read filter. (%2).").arg(read_filter, err_msg)), + QString(tr("The filter expression %1 isn't a valid read filter. (%2).").arg(read_filter, df_err->msg)), QMessageBox::Ok); - g_free(err_msg); + dfilter_error_free(df_err); continue; } } else { diff --git a/ui/logray/logray_main_window_slots.cpp b/ui/logray/logray_main_window_slots.cpp index d8465aca6d..70fd5b003c 100644 --- a/ui/logray/logray_main_window_slots.cpp +++ b/ui/logray/logray_main_window_slots.cpp @@ -161,7 +161,7 @@ bool LograyMainWindow::openCaptureFile(QString cf_path, QString read_filter, uns { QString file_name = ""; dfilter_t *rfcode = NULL; - gchar *err_msg; + df_error_t *df_err = NULL; int err; gboolean name_param; gboolean ret = true; @@ -194,7 +194,7 @@ bool LograyMainWindow::openCaptureFile(QString cf_path, QString read_filter, uns goto finish; } - if (dfilter_compile(qUtf8Printable(read_filter), &rfcode, &err_msg)) { + if (dfilter_compile(qUtf8Printable(read_filter), &rfcode, &df_err)) { cf_set_rfcode(CaptureFile::globalCapFile(), rfcode); } else { /* Not valid. Tell the user, and go back and run the file @@ -204,8 +204,9 @@ bool LograyMainWindow::openCaptureFile(QString cf_path, QString read_filter, uns QString("The filter expression ") + read_filter + QString(" isn't a valid display filter. (") + - err_msg + QString(")."), + df_err->msg + QString(")."), QMessageBox::Ok); + dfilter_error_free(df_err); if (!name_param) { // go back to the selection dialogue only if the file diff --git a/ui/qt/coloring_rules_dialog.cpp b/ui/qt/coloring_rules_dialog.cpp index 8dc1628dbe..9c446aa1fb 100644 --- a/ui/qt/coloring_rules_dialog.cpp +++ b/ui/qt/coloring_rules_dialog.cpp @@ -174,17 +174,17 @@ void ColoringRulesDialog::rowCountChanged() bool ColoringRulesDialog::isValidFilter(QString filter, QString * error) { dfilter_t *dfp = NULL; - gchar *err_msg; + df_error_t *df_err = NULL; - if (dfilter_compile(filter.toUtf8().constData(), &dfp, &err_msg)) { + if (dfilter_compile(filter.toUtf8().constData(), &dfp, &df_err)) { dfilter_free(dfp); return true; } - if (err_msg) + if (df_err) { - error->append(err_msg); - g_free(err_msg); + error->append(df_err->msg); + dfilter_error_free(df_err); } return false; diff --git a/ui/qt/iax2_analysis_dialog.cpp b/ui/qt/iax2_analysis_dialog.cpp index 07b9b42e01..29d08c6e69 100644 --- a/ui/qt/iax2_analysis_dialog.cpp +++ b/ui/qt/iax2_analysis_dialog.cpp @@ -294,12 +294,12 @@ Iax2AnalysisDialog::Iax2AnalysisDialog(QWidget &parent, CaptureFile &cf) : const gchar filter_text[] = "iax2 && (ip || ipv6)"; #endif dfilter_t *sfcode; - gchar *err_msg; + df_error_t *df_err; /* Try to compile the filter. */ - if (!dfilter_compile(filter_text, &sfcode, &err_msg)) { - err_str_ = QString(err_msg); - g_free(err_msg); + if (!dfilter_compile(filter_text, &sfcode, &df_err)) { + err_str_ = QString(df_err->msg); + dfilter_error_free(df_err); updateWidgets(); return; } diff --git a/ui/qt/io_graph_dialog.cpp b/ui/qt/io_graph_dialog.cpp index da8d94f38d..62482ff093 100644 --- a/ui/qt/io_graph_dialog.cpp +++ b/ui/qt/io_graph_dialog.cpp @@ -1660,12 +1660,12 @@ void IOGraph::setFilter(const QString &filter) if (!full_filter.isEmpty()) { dfilter_t *dfilter; bool status; - gchar *err_msg; - status = dfilter_compile(full_filter.toUtf8().constData(), &dfilter, &err_msg); + df_error_t *df_err = NULL; + status = dfilter_compile(full_filter.toUtf8().constData(), &dfilter, &df_err); dfilter_free(dfilter); if (!status) { - config_err_ = QString::fromUtf8(err_msg); - g_free(err_msg); + config_err_ = QString::fromUtf8(df_err->msg); + dfilter_error_free(df_err); filter_ = full_filter; return; } diff --git a/ui/qt/main.cpp b/ui/qt/main.cpp index b6073d323e..23da6a4083 100644 --- a/ui/qt/main.cpp +++ b/ui/qt/main.cpp @@ -451,6 +451,7 @@ int main(int argc, char *qt_argv[]) #endif #endif gchar *err_msg = NULL; + df_error_t *df_err = NULL; QString dfilter, read_filter; #ifdef HAVE_LIBPCAP @@ -982,13 +983,13 @@ int main(int argc, char *qt_argv[]) } else if (global_commandline_info.jfilter != NULL) { dfilter_t *jump_to_filter = NULL; /* try to compile given filter */ - if (!dfilter_compile(global_commandline_info.jfilter, &jump_to_filter, &err_msg)) { + if (!dfilter_compile(global_commandline_info.jfilter, &jump_to_filter, &df_err)) { // Similar code in MainWindow::mergeCaptureFile(). QMessageBox::warning(main_w, QObject::tr("Invalid Display Filter"), QObject::tr("The filter expression %1 isn't a valid display filter. (%2).") - .arg(global_commandline_info.jfilter, err_msg), + .arg(global_commandline_info.jfilter, df_err->msg), QMessageBox::Ok); - g_free(err_msg); + dfilter_error_free(df_err); } else { /* Filter ok, jump to the first packet matching the filter conditions. Default search direction is forward, but if diff --git a/ui/qt/widgets/syntax_line_edit.cpp b/ui/qt/widgets/syntax_line_edit.cpp index d5a3502236..776a7d20c5 100644 --- a/ui/qt/widgets/syntax_line_edit.cpp +++ b/ui/qt/widgets/syntax_line_edit.cpp @@ -201,9 +201,8 @@ bool SyntaxLineEdit::checkDisplayFilter(QString filter) } dfilter_t *dfp = NULL; - gchar *err_msg; - dfilter_loc_t loc; - if (dfilter_compile2(filter.toUtf8().constData(), &dfp, &err_msg, &loc)) { + df_error_t *df_err = NULL; + if (dfilter_compile(filter.toUtf8().constData(), &dfp, &df_err)) { GPtrArray *depr = NULL; if (dfp) { depr = dfilter_deprecated_tokens(dfp); @@ -231,9 +230,9 @@ bool SyntaxLineEdit::checkDisplayFilter(QString filter) } } else { setSyntaxState(SyntaxLineEdit::Invalid); - syntax_error_message_ = QString::fromUtf8(err_msg); - syntax_error_message_full_ = createSyntaxErrorMessageFull(filter, syntax_error_message_, loc.col_start, loc.col_len); - g_free(err_msg); + syntax_error_message_ = QString::fromUtf8(df_err->msg); + syntax_error_message_full_ = createSyntaxErrorMessageFull(filter, syntax_error_message_, df_err->loc.col_start, df_err->loc.col_len); + dfilter_error_free(df_err); } dfilter_free(dfp); diff --git a/ui/qt/wireshark_main_window.cpp b/ui/qt/wireshark_main_window.cpp index 76c31ed036..c395bfe6b8 100644 --- a/ui/qt/wireshark_main_window.cpp +++ b/ui/qt/wireshark_main_window.cpp @@ -1227,16 +1227,16 @@ void WiresharkMainWindow::mergeCaptureFile() char *tmpname; if (merge_dlg.merge(file_name, read_filter)) { - gchar *err_msg; + df_error_t *df_err = NULL; - if (!dfilter_compile(qUtf8Printable(read_filter), &rfcode, &err_msg)) { + if (!dfilter_compile(qUtf8Printable(read_filter), &rfcode, &df_err)) { /* Not valid. Tell the user, and go back and run the file selection box again once they dismiss the alert. */ // Similar to commandline_info.jfilter section in main(). QMessageBox::warning(this, tr("Invalid Read Filter"), - QString(tr("The filter expression %1 isn't a valid read filter. (%2).").arg(read_filter, err_msg)), + QString(tr("The filter expression %1 isn't a valid read filter. (%2).").arg(read_filter, df_err->msg)), QMessageBox::Ok); - g_free(err_msg); + dfilter_error_free(df_err); continue; } } else { @@ -3009,7 +3009,7 @@ QString WiresharkMainWindow::findRtpStreams(QVector *stream_id bool fwd_id_used, rev_id_used; const gchar filter_text[] = "rtp && rtp.version == 2 && rtp.ssrc && (ip || ipv6)"; dfilter_t *sfcode; - gchar *err_msg; + df_error_t *df_err = NULL; /* Try to get the hfid for "rtp.ssrc". */ int hfid_rtp_ssrc = proto_registrar_get_id_byname("rtp.ssrc"); @@ -3018,9 +3018,9 @@ QString WiresharkMainWindow::findRtpStreams(QVector *stream_id } /* Try to compile the filter. */ - if (!dfilter_compile(filter_text, &sfcode, &err_msg)) { - QString err = QString(err_msg); - g_free(err_msg); + if (!dfilter_compile(filter_text, &sfcode, &df_err)) { + QString err = QString(df_err->msg); + dfilter_error_free(df_err); return err; } diff --git a/ui/qt/wireshark_main_window_slots.cpp b/ui/qt/wireshark_main_window_slots.cpp index 15d5d12f9c..0a4f8ce0bd 100644 --- a/ui/qt/wireshark_main_window_slots.cpp +++ b/ui/qt/wireshark_main_window_slots.cpp @@ -188,7 +188,7 @@ bool WiresharkMainWindow::openCaptureFile(QString cf_path, QString read_filter, { QString file_name = ""; dfilter_t *rfcode = NULL; - gchar *err_msg; + df_error_t *df_err = NULL; int err; gboolean name_param; gboolean ret = true; @@ -221,7 +221,7 @@ bool WiresharkMainWindow::openCaptureFile(QString cf_path, QString read_filter, goto finish; } - if (dfilter_compile(qUtf8Printable(read_filter), &rfcode, &err_msg)) { + if (dfilter_compile(qUtf8Printable(read_filter), &rfcode, &df_err)) { cf_set_rfcode(CaptureFile::globalCapFile(), rfcode); } else { /* Not valid. Tell the user, and go back and run the file @@ -231,9 +231,9 @@ bool WiresharkMainWindow::openCaptureFile(QString cf_path, QString read_filter, QString("The filter expression ") + read_filter + QString(" isn't a valid display filter. (") + - err_msg + QString(")."), + df_err->msg + QString(")."), QMessageBox::Ok); - + dfilter_error_free(df_err); if (!name_param) { // go back to the selection dialogue only if the file // was selected from this dialogue diff --git a/ui/tap-rlc-graph.c b/ui/tap-rlc-graph.c index 0bfd9c7390..7147c2d913 100644 --- a/ui/tap-rlc-graph.c +++ b/ui/tap-rlc-graph.c @@ -110,7 +110,7 @@ rlc_lte_tap_info *select_rlc_lte_session(capture_file *cf, } /* No real filter yet */ - if (!dfilter_compile("rlc-lte", &sfcode, err_msg)) { + if (!dfilter_compile("rlc-lte", &sfcode, NULL)) { return NULL; } diff --git a/ui/tap-tcp-stream.c b/ui/tap-tcp-stream.c index 6afe110173..4440606fed 100644 --- a/ui/tap-tcp-stream.c +++ b/ui/tap-tcp-stream.c @@ -256,7 +256,7 @@ select_tcpip_session(capture_file *cf) epan_dissect_t edt; dfilter_t *sfcode; guint32 th_stream; - gchar *err_msg; + df_error_t *df_err; GString *error_string; th_t th = {0, {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}}; @@ -265,9 +265,9 @@ select_tcpip_session(capture_file *cf) } /* no real filter yet */ - if (!dfilter_compile("tcp", &sfcode, &err_msg)) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg); - g_free(err_msg); + if (!dfilter_compile("tcp", &sfcode, &df_err)) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", df_err->msg); + dfilter_error_free(df_err); return G_MAXUINT32; }