aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoão Valverde <j@v6e.pt>2021-10-15 11:02:48 +0100
committerJoão Valverde <j@v6e.pt>2021-10-15 13:06:51 +0100
commitc484ad0e5c6cadcda02a7079aa53b76be418c391 (patch)
tree01c0c7c8d7f841091c789388cbb29a28b51347cb
parent144dc1e2eefbb3e19b78ccb4a8c2c57bba9c212b (diff)
dfilter: Don't try to parse byte arrays as strings
It won't work with embedded null bytes so don't try. This is not an additional restriction, it just removes a hidden failure mode. To support matching embedded NUL bytes we would have to use an internal string representation other than null-terminated C strings (which doesn't seem very onerous with GString). Before: Filter: http.user_agent == 41:42:00:43 Constants: 00000 PUT_FVALUE "AB" <FT_STRING> -> reg#1 Instructions: 00000 READ_TREE http.user_agent -> reg#0 00001 IF-FALSE-GOTO 3 00002 ANY_EQ reg#0 == reg#1 00003 RETURN After: Filter: http.user_agent == 41:42:00:43 Constants: 00000 PUT_FVALUE "41:42:00:43" <FT_STRING> -> reg#1 Instructions: 00000 READ_TREE http.user_agent -> reg#0 00001 IF-FALSE-GOTO 3 00002 ANY_EQ reg#0 == reg#1 00003 RETURN
-rw-r--r--docbook/release-notes.adoc2
-rw-r--r--epan/ftypes/ftype-string.c28
-rw-r--r--test/suite_dfilter/group_string_type.py8
3 files changed, 13 insertions, 25 deletions
diff --git a/docbook/release-notes.adoc b/docbook/release-notes.adoc
index 00ec34b527..c4b84ad415 100644
--- a/docbook/release-notes.adoc
+++ b/docbook/release-notes.adoc
@@ -106,6 +106,8 @@ The following features are new (or have been significantly updated) since versio
* Display filter syntax:
** Protocols always parse unquoted strings as byte values. Before an expression such as "tcp contains ff.fg" would look for the string "ff.fg" if it does not
match a valid byte array specification. Now this is a syntax error. Use double-quotes to match literal strings.
+** For string comparisons literal byte arrays are always interpreted as unquoted literal strings. This avoids unexpected results with embedded NUL bytes.
+ For example "http.user_agent contains aa:bb" tries to match "aa:bb". Avoid this usage, always use double-quotes: http.user_agent contains "\xaa\xbb".
// === Removed Features and Support
diff --git a/epan/ftypes/ftype-string.c b/epan/ftypes/ftype-string.c
index 28d5636fab..21c76dfa8b 100644
--- a/epan/ftypes/ftype-string.c
+++ b/epan/ftypes/ftype-string.c
@@ -89,29 +89,11 @@ val_from_string(fvalue_t *fv, const char *s, gchar **err_msg _U_)
static gboolean
val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
{
- fvalue_t *fv_bytes;
-
- /* Does this look like a byte-string? */
- fv_bytes = fvalue_from_unparsed(FT_BYTES, s, TRUE, NULL);
- if (fv_bytes) {
- /* Free up the old value, if we have one */
- string_fvalue_free(fv);
-
- /* Copy the bytes over to a string and terminate it
- * with a NUL. XXX - what if the user embeds a NUL
- * in the middle of the byte string? */
- int num_bytes = fv_bytes->value.bytes->len;
-
- fv->value.string = (gchar *)g_malloc(num_bytes + 1);
- memcpy(fv->value.string, fv_bytes->value.bytes->data, num_bytes);
- fv->value.string[num_bytes] = '\0';
-
- FVALUE_FREE(fv_bytes);
- return TRUE;
- } else {
- /* Just turn it into a string */
- return val_from_string(fv, s, err_msg);
- }
+ /* Just turn it into a string */
+ /* XXX Should probably be a syntax error instead. It's more user-friendly to ask the
+ * user to be explicit about the meaning of unparsed than them trying to figure out
+ * why a valid filter expression is giving wrong results. */
+ return val_from_string(fv, s, err_msg);
}
static guint
diff --git a/test/suite_dfilter/group_string_type.py b/test/suite_dfilter/group_string_type.py
index 6ad989d6ae..9298646270 100644
--- a/test/suite_dfilter/group_string_type.py
+++ b/test/suite_dfilter/group_string_type.py
@@ -125,13 +125,17 @@ class case_string(unittest.TestCase):
checkDFilterCount(dfilter, 0)
def test_contains_5(self, checkDFilterCount):
- dfilter = 'http.request.method contains 50:4f:53:54' # "POST"
+ dfilter = 'http.request.method contains "\x50\x4f\x53\x54"' # "POST"
checkDFilterCount(dfilter, 0)
def test_contains_6(self, checkDFilterCount):
- dfilter = 'http.request.method contains 48:45:41:44' # "HEAD"
+ dfilter = 'http.request.method contains "\x48\x45\x41\x44"' # "HEAD"
checkDFilterCount(dfilter, 1)
+ def test_contains_6(self, checkDFilterCount):
+ dfilter = 'http.request.method contains 48:45:41:44' # "48:45:41:44"
+ checkDFilterCount(dfilter, 0)
+
def test_contains_fail_0(self, checkDFilterCount):
dfilter = 'http.user_agent contains "update"'
checkDFilterCount(dfilter, 0)