aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dfilter
diff options
context:
space:
mode:
authorJoão Valverde <j@v6e.pt>2021-10-14 12:56:57 +0100
committerJoão Valverde <j@v6e.pt>2021-10-14 16:49:23 +0100
commit0d3bfedfb0fa3afd3d7787873823b80796097003 (patch)
tree7c45b081ba5f804feaa7c31f6a4af626bd660f52 /epan/dfilter
parente91b5beafdeb8a2a1366e802fee2c2a3e346b054 (diff)
dfilter: Fixup deprecated tokens initialization
Always use the internal API to access "deprecated" and initialize the data structure on demand. This fixes a null pointer dereference introduced previously. Use reference counting to share the array cleanly and avoid memory leaks. Keep the pointer in dfwork_t.
Diffstat (limited to 'epan/dfilter')
-rw-r--r--epan/dfilter/dfilter-int.h3
-rw-r--r--epan/dfilter/dfilter.c53
-rw-r--r--epan/dfilter/scanner.l4
-rw-r--r--epan/dfilter/semcheck.c4
4 files changed, 23 insertions, 41 deletions
diff --git a/epan/dfilter/dfilter-int.h b/epan/dfilter/dfilter-int.h
index eff2946d98..9e6cef482c 100644
--- a/epan/dfilter/dfilter-int.h
+++ b/epan/dfilter/dfilter-int.h
@@ -53,7 +53,6 @@ typedef struct {
GString* quoted_string;
gboolean raw_string;
gboolean in_set; /* true if parsing set elements for the membership operator */
- GPtrArray *deprecated;
} df_scanner_state_t;
/* Constructor/Destructor prototypes for Lemon Parser */
@@ -76,7 +75,7 @@ void
dfilter_parse_fail(dfwork_t *dfw, const char *format, ...) G_GNUC_PRINTF(2, 3);
void
-add_deprecated_token(GPtrArray *deprecated, const char *token);
+add_deprecated_token(dfwork_t *dfw, const char *token);
void
free_deprecated(GPtrArray *deprecated);
diff --git a/epan/dfilter/dfilter.c b/epan/dfilter/dfilter.c
index e2a1a37069..1c47caa5a6 100644
--- a/epan/dfilter/dfilter.c
+++ b/epan/dfilter/dfilter.c
@@ -153,7 +153,7 @@ dfilter_resolve_unparsed(dfwork_t *dfw, stnode_t *node)
hfinfo = proto_registrar_get_byalias(name);
if (hfinfo != NULL) {
/* It's an aliased field name */
- add_deprecated_token(dfw->deprecated, name);
+ add_deprecated_token(dfw, name);
stnode_replace(node, STTYPE_FIELD, hfinfo);
return node;
}
@@ -204,13 +204,15 @@ dfilter_cleanup(void)
}
static dfilter_t*
-dfilter_new(void)
+dfilter_new(GPtrArray *deprecated)
{
dfilter_t *df;
df = g_new0(dfilter_t, 1);
df->insns = NULL;
- df->deprecated = NULL;
+
+ if (deprecated)
+ df->deprecated = g_ptr_array_ref(deprecated);
return df;
}
@@ -253,13 +255,8 @@ dfilter_free(dfilter_t *df)
g_list_free(df->registers[i]);
}
- if (df->deprecated) {
- for (i = 0; i < df->deprecated->len; ++i) {
- gchar *depr = (gchar *)g_ptr_array_index(df->deprecated, i);
- g_free(depr);
- }
- g_ptr_array_free(df->deprecated, TRUE);
- }
+ if (df->deprecated)
+ g_ptr_array_unref(df->deprecated);
g_free(df->registers);
g_free(df->attempted_load);
@@ -302,6 +299,9 @@ dfwork_free(dfwork_t *dfw)
free_insns(dfw->consts);
}
+ if (dfw->deprecated)
+ g_ptr_array_unref(dfw->deprecated);
+
/*
* We don't free the error message string; our caller will return
* it to its caller.
@@ -346,10 +346,15 @@ const char *tokenstr(int token)
}
void
-add_deprecated_token(GPtrArray *deprecated, const char *token)
+add_deprecated_token(dfwork_t *dfw, const char *token)
{
+ if (dfw->deprecated == NULL)
+ dfw->deprecated = g_ptr_array_new_full(0, g_free);
+
+ GPtrArray *deprecated = dfw->deprecated;
+
for (guint i = 0; i < deprecated->len; i++) {
- const char *str = (const char *)g_ptr_array_index(deprecated, i);
+ const char *str = g_ptr_array_index(deprecated, i);
if (g_ascii_strcasecmp(token, str) == 0) {
/* It's already in our list */
return;
@@ -358,16 +363,6 @@ add_deprecated_token(GPtrArray *deprecated, const char *token)
g_ptr_array_add(deprecated, g_strdup(token));
}
-void
-free_deprecated(GPtrArray *deprecated)
-{
- for (guint i = 0; i < deprecated->len; ++i) {
- gpointer *depr = g_ptr_array_index(deprecated,i);
- g_free(depr);
- }
- g_ptr_array_free(deprecated, TRUE);
-}
-
gboolean
dfilter_compile(const gchar *text, dfilter_t **dfp, gchar **err_msg)
{
@@ -379,8 +374,6 @@ dfilter_compile(const gchar *text, dfilter_t **dfp, gchar **err_msg)
yyscan_t scanner;
YY_BUFFER_STATE in_buffer;
gboolean failure = FALSE;
- /* XXX, GHashTable */
- GPtrArray *deprecated;
ws_assert(dfp);
@@ -409,13 +402,10 @@ dfilter_compile(const gchar *text, dfilter_t **dfp, gchar **err_msg)
dfw = dfwork_new();
- deprecated = g_ptr_array_new();
-
state.dfw = dfw;
state.quoted_string = NULL;
state.in_set = FALSE;
state.raw_string = FALSE;
- state.deprecated = deprecated;
df_set_extra(&state, scanner);
@@ -480,13 +470,10 @@ dfilter_compile(const gchar *text, dfilter_t **dfp, gchar **err_msg)
* it and set *dfp to NULL */
if (dfw->st_root == NULL) {
*dfp = NULL;
- free_deprecated(deprecated);
}
else {
log_syntax_tree(LOG_LEVEL_NOISY, dfw->st_root, "Syntax tree before semantic check");
- dfw->deprecated = deprecated;
-
/* Check semantics and do necessary type conversion*/
if (!dfw_semcheck(dfw)) {
goto FAILURE;
@@ -498,7 +485,7 @@ dfilter_compile(const gchar *text, dfilter_t **dfp, gchar **err_msg)
dfw_gencode(dfw);
/* Tuck away the bytecode in the dfilter_t */
- dfilter = dfilter_new();
+ dfilter = dfilter_new(dfw->deprecated);
dfilter->insns = dfw->insns;
dfilter->consts = dfw->consts;
dfw->insns = NULL;
@@ -516,9 +503,6 @@ dfilter_compile(const gchar *text, dfilter_t **dfp, gchar **err_msg)
/* Initialize constants */
dfvm_init_const(dfilter);
- /* Add any deprecated items */
- dfilter->deprecated = deprecated;
-
/* And give it to the user. */
*dfp = dfilter;
}
@@ -537,7 +521,6 @@ FAILURE:
global_dfw = NULL;
dfwork_free(dfw);
}
- free_deprecated(deprecated);
if (err_msg != NULL) {
/*
* Default error message.
diff --git a/epan/dfilter/scanner.l b/epan/dfilter/scanner.l
index 8a5c00b9c7..450d4564c9 100644
--- a/epan/dfilter/scanner.l
+++ b/epan/dfilter/scanner.l
@@ -137,11 +137,11 @@ static int simple(int token, const char *token_value);
"==" return SIMPLE(TOKEN_TEST_EQ);
"eq" return SIMPLE(TOKEN_TEST_EQ);
"!=" {
- add_deprecated_token(yyextra->deprecated, "!=");
+ add_deprecated_token(yyextra->dfw, "!=");
return SIMPLE(TOKEN_TEST_NE);
}
"ne" {
- add_deprecated_token(yyextra->deprecated, "ne");
+ add_deprecated_token(yyextra->dfw, "ne");
return SIMPLE(TOKEN_TEST_NE);
}
">" return SIMPLE(TOKEN_TEST_GT);
diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c
index 56662defbf..02bea9194b 100644
--- a/epan/dfilter/semcheck.c
+++ b/epan/dfilter/semcheck.c
@@ -1378,7 +1378,7 @@ check_test(dfwork_t *dfw, stnode_t *st_node)
sttype_test_get(st_arg1, &st_arg_op, NULL, NULL);
if (st_arg_op == TEST_OP_AND || st_arg_op == TEST_OP_OR) {
if (st_op != st_arg_op && !stnode_inside_parens(st_arg1))
- g_ptr_array_add(dfw->deprecated, g_strdup("suggest parentheses around '&&' within '||'"));
+ add_deprecated_token(dfw, "suggest parentheses around '&&' within '||'");
}
}
@@ -1386,7 +1386,7 @@ check_test(dfwork_t *dfw, stnode_t *st_node)
sttype_test_get(st_arg2, &st_arg_op, NULL, NULL);
if (st_arg_op == TEST_OP_AND || st_arg_op == TEST_OP_OR) {
if (st_op != st_arg_op && !stnode_inside_parens(st_arg2))
- g_ptr_array_add(dfw->deprecated, g_strdup("suggest parentheses around '&&' within '||'"));
+ add_deprecated_token(dfw, "suggest parentheses around '&&' within '||'");
}
}