diff --git a/docbook/release-notes.adoc b/docbook/release-notes.adoc index e76c4fa195..a8e9d3c085 100644 --- a/docbook/release-notes.adoc +++ b/docbook/release-notes.adoc @@ -56,6 +56,11 @@ They previously shipped with Npcap 1.20. Also the timestamp format now allows the second-fractions to be placed anywhere in the timestamp and it will be stored with nanosecond instead of microsecond precision. +* Display filter literal strings can now be specified using raw string syntax, + identical to raw strings in the Python programming language. This is useful + to avoid the complexity of using two levels of character escapes with regular + expressions. + * Significant RTP Player redesign and improvements (see Wireshark User Documentation, https://www.wireshark.org/docs/wsug_html_chunked/ChTelPlayingCalls.html[Playing VoIP Calls] and https://www.wireshark.org/docs/wsug_html_chunked/_rtp.html#ChTelRtpPlayer[RTP Player Window]) diff --git a/epan/dfilter/dfilter-int.h b/epan/dfilter/dfilter-int.h index 9d53353954..648892aed6 100644 --- a/epan/dfilter/dfilter-int.h +++ b/epan/dfilter/dfilter-int.h @@ -50,6 +50,7 @@ typedef struct { typedef struct { dfwork_t *dfw; GString* quoted_string; + gboolean raw_string; gboolean in_set; /* true if parsing set elements for the membership operator */ } df_scanner_state_t; diff --git a/epan/dfilter/dfilter.c b/epan/dfilter/dfilter.c index 850c27bdc0..59924eb239 100644 --- a/epan/dfilter/dfilter.c +++ b/epan/dfilter/dfilter.c @@ -240,6 +240,7 @@ dfilter_compile(const gchar *text, dfilter_t **dfp, gchar **err_msg) state.dfw = dfw; state.quoted_string = NULL; state.in_set = FALSE; + state.raw_string = FALSE; df_set_extra(&state, scanner); diff --git a/epan/dfilter/scanner.l b/epan/dfilter/scanner.l index f04c2ee561..fbef746c9d 100644 --- a/epan/dfilter/scanner.l +++ b/epan/dfilter/scanner.l @@ -219,7 +219,7 @@ static void mark_lval_deprecated(const char *s); return SCAN_FAILED; } -\042 { +[rR]{0,1}\042 { /* start quote of a quoted string */ /* The example of how to scan for strings was taken from the flex 2.5.4 manual, from the section "Start Conditions". @@ -238,6 +238,21 @@ static void mark_lval_deprecated(const char *s); about to set it in the next line. */ } yyextra->quoted_string = g_string_new(""); + if (yytext[0] == 'r' || yytext[0] == 'R') { + /* + * This is a raw string (like in Python). Rules: 1) The two + * escape sequences are \\ and \". 2) Backslashes are + * preserved. 3) Double quotes in the string must be escaped. + * Corollary: Strings cannot end with an odd number of + * backslashes. + * Example: r"a\b\x12\"\\" is the string (including the implicit NUL terminator) + * {'a', '\\', 'b', '\\', 'x', '1', '2', '\\', '"', '\\'. '\\', '\0'} + */ + yyextra->raw_string = TRUE; + } + else { + yyextra->raw_string = FALSE; + } } <> { @@ -263,28 +278,43 @@ static void mark_lval_deprecated(const char *s); \\[0-7]{1,3} { /* octal sequence */ - unsigned long result; - result = strtoul(yytext + 1, NULL, 8); - if (result > 0xff) { - g_string_free(yyextra->quoted_string, TRUE); - yyextra->quoted_string = NULL; - dfilter_fail(yyextra->dfw, "%s is larger than 255.", yytext); - return SCAN_FAILED; + if (yyextra->raw_string) { + g_string_append(yyextra->quoted_string, yytext); + } + else { + unsigned long result; + result = strtoul(yytext + 1, NULL, 8); + if (result > 0xff) { + g_string_free(yyextra->quoted_string, TRUE); + yyextra->quoted_string = NULL; + dfilter_fail(yyextra->dfw, "%s is larger than 255.", yytext); + return SCAN_FAILED; + } + g_string_append_c(yyextra->quoted_string, (gchar) result); } - g_string_append_c(yyextra->quoted_string, (gchar) result); } \\x[[:xdigit:]]{1,2} { /* hex sequence */ - unsigned long result; - result = strtoul(yytext + 2, NULL, 16); - g_string_append_c(yyextra->quoted_string, (gchar) result); + if (yyextra->raw_string) { + g_string_append(yyextra->quoted_string, yytext); + } + else { + unsigned long result; + result = strtoul(yytext + 2, NULL, 16); + g_string_append_c(yyextra->quoted_string, (gchar) result); + } } \\. { /* escaped character */ - g_string_append_c(yyextra->quoted_string, yytext[1]); + if (yyextra->raw_string) { + g_string_append(yyextra->quoted_string, yytext); + } + else { + g_string_append_c(yyextra->quoted_string, yytext[1]); + } } [^\\\042]+ { diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c index dc3a947f9d..6245f7fd1f 100644 --- a/epan/dfilter/semcheck.c +++ b/epan/dfilter/semcheck.c @@ -409,6 +409,8 @@ dfilter_g_regex_from_string(dfwork_t *dfw, const char *s) */ cflags = (GRegexCompileFlags)(cflags | G_REGEX_RAW); + DebugLog(("Compile regex pattern: '%s'\n", s)); + pcre = g_regex_new( s, /* pattern */ cflags, /* Compile options */