From 24443fa33ad20a178536e7d3c21c3b2bcf1167a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Valverde?= Date: Sun, 10 Apr 2022 18:19:45 +0100 Subject: [PATCH] tshark: Add underline to dfilter errors $ tshark -Y 'frame.number == 123foobar and ip' -r /dev/null tshark: "123foobar" is not a valid number. frame.number == 123foobar and ip ^~~~~~~~~ --- epan/dfilter/dfilter.h | 3 +++ tshark.c | 13 ++++++++++--- wsutil/str_util.c | 20 ++++++++++++++++++++ wsutil/str_util.h | 3 +++ 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/epan/dfilter/dfilter.h b/epan/dfilter/dfilter.h index 7cbb4b1539..031ed667ff 100644 --- a/epan/dfilter/dfilter.h +++ b/epan/dfilter/dfilter.h @@ -67,6 +67,9 @@ dfilter_compile_real(const gchar *text, dfilter_t **dfp, #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) + /* Frees all memory used by dfilter, and frees * the dfilter itself. */ WS_DLL_PUBLIC diff --git a/tshark.c b/tshark.c index d39ffcd33f..012c6ded3d 100644 --- a/tshark.c +++ b/tshark.c @@ -722,7 +722,7 @@ must_do_dissection(dfilter_t *rfcode, dfilter_t *dfcode, int main(int argc, char *argv[]) { - char *err_msg; + char *err_msg, *err_msg_cont; static const struct report_message_routines tshark_report_routines = { failure_message, failure_message, @@ -777,6 +777,7 @@ main(int argc, char *argv[]) gchar *volatile dfilter = NULL; dfilter_t *rfcode = NULL; dfilter_t *dfcode = NULL; + dfilter_loc_t df_loc; e_prefs *prefs_p; gchar *output_only = NULL; gchar *volatile pdu_export_arg = NULL; @@ -2013,9 +2014,12 @@ main(int argc, char *argv[]) if (rfilter != NULL) { ws_debug("Compiling read filter: '%s'", rfilter); - if (!dfilter_compile(rfilter, &rfcode, &err_msg)) { + if (!dfilter_compile2(rfilter, &rfcode, &err_msg, &df_loc)) { cmdarg_err("%s", err_msg); + err_msg_cont = ws_strdup_error_offset(NULL, df_loc.col_start, df_loc.col_len); + cmdarg_err_cont(" %s\n %s\n", rfilter, err_msg_cont); g_free(err_msg); + g_free(err_msg_cont); epan_cleanup(); extcap_cleanup(); @@ -2040,9 +2044,12 @@ main(int argc, char *argv[]) if (dfilter != NULL) { ws_debug("Compiling display filter: '%s'", dfilter); - if (!dfilter_compile(dfilter, &dfcode, &err_msg)) { + if (!dfilter_compile2(dfilter, &dfcode, &err_msg, &df_loc)) { cmdarg_err("%s", err_msg); + err_msg_cont = ws_strdup_error_offset(NULL, df_loc.col_start, df_loc.col_len); + cmdarg_err_cont(" %s\n %s\n", dfilter, err_msg_cont); g_free(err_msg); + g_free(err_msg_cont); epan_cleanup(); extcap_cleanup(); diff --git a/wsutil/str_util.c b/wsutil/str_util.c index 099e331295..71ac049fe0 100644 --- a/wsutil/str_util.c +++ b/wsutil/str_util.c @@ -548,6 +548,26 @@ ws_strerrorname_r(int errnum, char *buf, size_t buf_size) return buf; } +char * +ws_strdup_error_offset(wmem_allocator_t *allocator, int offset, size_t len) +{ + if (offset < 0) + return NULL; + + wmem_strbuf_t *buf = wmem_strbuf_sized_new(allocator, offset + len, 0); + + for (int i = 0; i < offset; i++) { + wmem_strbuf_append_c(buf, ' '); + } + wmem_strbuf_append_c(buf, '^'); + + for (size_t l = len; l > 1; l--) { + wmem_strbuf_append_c(buf, '~'); + } + + return wmem_strbuf_finalize(buf); +} + /* * Editor modelines - https://www.wireshark.org/tools/modelines.html * diff --git a/wsutil/str_util.h b/wsutil/str_util.h index be6ce12485..d3278f8369 100644 --- a/wsutil/str_util.h +++ b/wsutil/str_util.h @@ -218,6 +218,9 @@ gchar printable_char_or_period(gchar c); WS_DLL_PUBLIC WS_RETNONNULL const char *ws_strerrorname_r(int errnum, char *buf, size_t buf_size); +WS_DLL_PUBLIC +char *ws_strdup_error_offset(wmem_allocator_t *allocator, int offset, size_t len); + /* To pass one of two strings, singular or plural */ #define plurality(d,s,p) ((d) == 1 ? (s) : (p))