aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dfilter
diff options
context:
space:
mode:
authorJoão Valverde <j@v6e.pt>2021-10-01 11:31:20 +0100
committerWireshark GitLab Utility <gerald+gitlab-utility@wireshark.org>2021-10-01 16:04:37 +0000
commit2c55bffb410c69555432b1842590714247d85b2d (patch)
treec40c90c52ba1569c91073a9c90d2b8a7cfef9891 /epan/dfilter
parentdb18865e5517484ed7ce3aebc2e8695d5bf7bedf (diff)
dfilter: Improve syntax error message
Pass simple token value and use it for the error message. This string is freed in the parser destructor.
Diffstat (limited to 'epan/dfilter')
-rw-r--r--epan/dfilter/grammar.lemon5
-rw-r--r--epan/dfilter/scanner.l80
-rw-r--r--epan/dfilter/syntax-tree.c64
3 files changed, 71 insertions, 78 deletions
diff --git a/epan/dfilter/grammar.lemon b/epan/dfilter/grammar.lemon
index 66158129be..1d7d4e73db 100644
--- a/epan/dfilter/grammar.lemon
+++ b/epan/dfilter/grammar.lemon
@@ -79,7 +79,10 @@ any "error" symbols are shifted, if possible. */
switch(stnode_type_id(TOKEN)) {
case STTYPE_UNINITIALIZED:
- dfilter_fail(dfw, "Syntax error.");
+ if ((TOKEN)->token_value != NULL)
+ dfilter_fail(dfw, "Syntax error near \"%s\".", stnode_token_value(TOKEN));
+ else
+ dfilter_fail(dfw, "Syntax error.");
break;
case STTYPE_TEST:
dfilter_fail(dfw, "Syntax error, TEST.");
diff --git a/epan/dfilter/scanner.l b/epan/dfilter/scanner.l
index 0ff0d906be..77870c5fa3 100644
--- a/epan/dfilter/scanner.l
+++ b/epan/dfilter/scanner.l
@@ -88,7 +88,8 @@ static int set_lval_str(int token, const char *token_value);
static int set_lval_field(int token, header_field_info *hfinfo, const char *token_value);
static int set_lval_func(int token, df_func_def_t *func, const char *token_value);
static int set_lval_int(dfwork_t *dfw, int token, const char *token_value);
-static int simple(int token);
+static int simple(int token, const char *token_value);
+#define SIMPLE(token) simple(token, yytext)
static gboolean str_to_gint32(dfwork_t *dfw, const char *s, gint32* pint);
/*
@@ -117,61 +118,61 @@ static gboolean str_to_gint32(dfwork_t *dfw, const char *s, gint32* pint);
* should have used commas from the beginning, but now we are stuck with
* whitespace as separators. */
if (yyextra->in_set) {
- return simple(TOKEN_WHITESPACE);
+ return simple(TOKEN_WHITESPACE, NULL);
}
}
-"(" return simple(TOKEN_LPAREN);
-")" return simple(TOKEN_RPAREN);
-"," return simple(TOKEN_COMMA);
+"(" return SIMPLE(TOKEN_LPAREN);
+")" return SIMPLE(TOKEN_RPAREN);
+"," return SIMPLE(TOKEN_COMMA);
"{"[[:blank:]\n]* {
yyextra->in_set = TRUE;
- return simple(TOKEN_LBRACE);
+ return simple(TOKEN_LBRACE, "{");
}
-[[:blank:]\n]*".."[[:blank:]\n]* return simple(TOKEN_DOTDOT);
+[[:blank:]\n]*".."[[:blank:]\n]* return simple(TOKEN_DOTDOT, "..");
[[:blank:]\n]*"}" {
yyextra->in_set = FALSE;
- return simple(TOKEN_RBRACE);
+ return simple(TOKEN_RBRACE, "}");
}
-"==" return simple(TOKEN_TEST_EQ);
-"eq" return simple(TOKEN_TEST_EQ);
+"==" return SIMPLE(TOKEN_TEST_EQ);
+"eq" return SIMPLE(TOKEN_TEST_EQ);
"!=" {
add_deprecated_token(yyextra->deprecated, "!=");
- return simple(TOKEN_TEST_NE);
+ return SIMPLE(TOKEN_TEST_NE);
}
"ne" {
add_deprecated_token(yyextra->deprecated, "ne");
- return simple(TOKEN_TEST_NE);
-}
-">" return simple(TOKEN_TEST_GT);
-"gt" return simple(TOKEN_TEST_GT);
-">=" return simple(TOKEN_TEST_GE);
-"ge" return simple(TOKEN_TEST_GE);
-"<" return simple(TOKEN_TEST_LT);
-"lt" return simple(TOKEN_TEST_LT);
-"<=" return simple(TOKEN_TEST_LE);
-"le" return simple(TOKEN_TEST_LE);
-"bitwise_and" return simple(TOKEN_TEST_BITWISE_AND);
-"&" return simple(TOKEN_TEST_BITWISE_AND);
-"contains" return simple(TOKEN_TEST_CONTAINS);
-"~" return simple(TOKEN_TEST_MATCHES);
-"matches" return simple(TOKEN_TEST_MATCHES);
-"!" return simple(TOKEN_TEST_NOT);
-"not" return simple(TOKEN_TEST_NOT);
-"&&" return simple(TOKEN_TEST_AND);
-"and" return simple(TOKEN_TEST_AND);
-"||" return simple(TOKEN_TEST_OR);
-"or" return simple(TOKEN_TEST_OR);
-"in" return simple(TOKEN_TEST_IN);
+ return SIMPLE(TOKEN_TEST_NE);
+}
+">" return SIMPLE(TOKEN_TEST_GT);
+"gt" return SIMPLE(TOKEN_TEST_GT);
+">=" return SIMPLE(TOKEN_TEST_GE);
+"ge" return SIMPLE(TOKEN_TEST_GE);
+"<" return SIMPLE(TOKEN_TEST_LT);
+"lt" return SIMPLE(TOKEN_TEST_LT);
+"<=" return SIMPLE(TOKEN_TEST_LE);
+"le" return SIMPLE(TOKEN_TEST_LE);
+"bitwise_and" return SIMPLE(TOKEN_TEST_BITWISE_AND);
+"&" return SIMPLE(TOKEN_TEST_BITWISE_AND);
+"contains" return SIMPLE(TOKEN_TEST_CONTAINS);
+"~" return SIMPLE(TOKEN_TEST_MATCHES);
+"matches" return SIMPLE(TOKEN_TEST_MATCHES);
+"!" return SIMPLE(TOKEN_TEST_NOT);
+"not" return SIMPLE(TOKEN_TEST_NOT);
+"&&" return SIMPLE(TOKEN_TEST_AND);
+"and" return SIMPLE(TOKEN_TEST_AND);
+"||" return SIMPLE(TOKEN_TEST_OR);
+"or" return SIMPLE(TOKEN_TEST_OR);
+"in" return SIMPLE(TOKEN_TEST_IN);
"[" {
BEGIN(RANGE_INT);
- return simple(TOKEN_LBRACKET);
+ return SIMPLE(TOKEN_LBRACKET);
}
<RANGE_INT>[+-]?[[:digit:]]+ {
@@ -186,22 +187,22 @@ static gboolean str_to_gint32(dfwork_t *dfw, const char *s, gint32* pint);
<RANGE_INT,RANGE_PUNCT>":" {
BEGIN(RANGE_INT);
- return simple(TOKEN_COLON);
+ return SIMPLE(TOKEN_COLON);
}
<RANGE_PUNCT>"-" {
BEGIN(RANGE_INT);
- return simple(TOKEN_HYPHEN);
+ return SIMPLE(TOKEN_HYPHEN);
}
<RANGE_INT,RANGE_PUNCT>"," {
BEGIN(RANGE_INT);
- return simple(TOKEN_COMMA);
+ return SIMPLE(TOKEN_COMMA);
}
<RANGE_INT,RANGE_PUNCT>"]" {
BEGIN(INITIAL);
- return simple(TOKEN_RBRACKET);
+ return SIMPLE(TOKEN_RBRACKET);
}
/* Error if none of the above while scanning a range (slice) */
@@ -444,7 +445,7 @@ static gboolean str_to_gint32(dfwork_t *dfw, const char *s, gint32* pint);
DIAG_ON_FLEX
static int
-simple(int token)
+simple(int token, const char *token_value)
{
switch (token) {
case TOKEN_LPAREN:
@@ -475,6 +476,7 @@ simple(int token)
default:
ws_assert_not_reached();
}
+ stnode_init(df_lval, STTYPE_UNINITIALIZED, NULL, token_value);
return token;
}
diff --git a/epan/dfilter/syntax-tree.c b/epan/dfilter/syntax-tree.c
index 047aae25d6..fe6e48bf0c 100644
--- a/epan/dfilter/syntax-tree.c
+++ b/epan/dfilter/syntax-tree.c
@@ -76,15 +76,17 @@ sttype_lookup(sttype_id_t type_id)
return result;
}
-
-stnode_t*
-stnode_new(sttype_id_t type_id, gpointer data, const char *token_value)
+void
+stnode_init(stnode_t *node, sttype_id_t type_id, gpointer data, const char *token_value)
{
sttype_t *type;
- stnode_t *node;
- node = g_new0(stnode_t, 1);
- node->magic = STNODE_MAGIC;
+ ws_assert_magic(node, STNODE_MAGIC);
+ ws_assert(!node->type);
+ ws_assert(!node->data);
+ ws_assert(!node->token_value);
+ node->flags = 0;
+ node->value = 0;
if (type_id == STTYPE_UNINITIALIZED) {
node->type = NULL;
@@ -103,6 +105,24 @@ stnode_new(sttype_id_t type_id, gpointer data, const char *token_value)
}
node->token_value = g_strdup(token_value);
+}
+
+void
+stnode_init_int(stnode_t *node, sttype_id_t type_id, gint32 value, const char *token_value)
+{
+ stnode_init(node, type_id, NULL, token_value);
+ node->value = value;
+}
+
+stnode_t*
+stnode_new(sttype_id_t type_id, gpointer data, const char *token_value)
+{
+ stnode_t *node;
+
+ node = g_new0(stnode_t, 1);
+ node->magic = STNODE_MAGIC;
+
+ stnode_init(node, type_id, data, token_value);
return node;
}
@@ -136,38 +156,6 @@ stnode_dup(const stnode_t *org)
}
void
-stnode_init(stnode_t *node, sttype_id_t type_id, gpointer data, const char *token_value)
-{
- sttype_t *type;
-
- ws_assert_magic(node, STNODE_MAGIC);
- ws_assert(!node->type);
- ws_assert(!node->data);
- ws_assert(!node->token_value);
-
- type = sttype_lookup(type_id);
- ws_assert(type);
- node->type = type;
- node->flags = 0;
-
- if (type->func_new) {
- node->data = type->func_new(data);
- }
- else {
- node->data = data;
- }
- node->value = 0;
- node->token_value = g_strdup(token_value);
-}
-
-void
-stnode_init_int(stnode_t *node, sttype_id_t type_id, gint32 value, const char *token_value)
-{
- stnode_init(node, type_id, NULL, token_value);
- node->value = value;
-}
-
-void
stnode_free(stnode_t *node)
{
ws_assert_magic(node, STNODE_MAGIC);