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.
This commit is contained in:
parent
e91b5beafd
commit
0d3bfedfb0
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 '||'");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue