diff --git a/lib/filterx/expr-getattr.c b/lib/filterx/expr-getattr.c index e20d8ff884..ada4d74ff0 100644 --- a/lib/filterx/expr-getattr.c +++ b/lib/filterx/expr-getattr.c @@ -102,7 +102,7 @@ _free(FilterXExpr *s) /* NOTE: takes the object reference */ FilterXExpr * -filterx_getattr_new(FilterXExpr *operand, const gchar *attr_name) +filterx_getattr_new(FilterXExpr *operand, FilterXString *attr_name) { FilterXGetAttr *self = g_new0(FilterXGetAttr, 1); @@ -112,6 +112,8 @@ filterx_getattr_new(FilterXExpr *operand, const gchar *attr_name) self->super.is_set = _isset; self->super.free_fn = _free; self->operand = operand; - self->attr = filterx_string_new(attr_name, -1); + + self->attr = (FilterXObject *) attr_name; + return &self->super; } diff --git a/lib/filterx/expr-getattr.h b/lib/filterx/expr-getattr.h index 5a960ec808..044b4fa723 100644 --- a/lib/filterx/expr-getattr.h +++ b/lib/filterx/expr-getattr.h @@ -24,8 +24,9 @@ #define FILTERX_GETATTR_H_INCLUDED #include "filterx/filterx-expr.h" +#include "filterx/object-string.h" -FilterXExpr *filterx_getattr_new(FilterXExpr *lhs, const gchar *attr_name); +FilterXExpr *filterx_getattr_new(FilterXExpr *lhs, FilterXString *attr_name); #endif diff --git a/lib/filterx/expr-setattr.c b/lib/filterx/expr-setattr.c index 5745976684..c88a2d4790 100644 --- a/lib/filterx/expr-setattr.c +++ b/lib/filterx/expr-setattr.c @@ -85,7 +85,7 @@ _free(FilterXExpr *s) /* Takes reference of object and new_value */ FilterXExpr * -filterx_setattr_new(FilterXExpr *object, const gchar *attr_name, FilterXExpr *new_value) +filterx_setattr_new(FilterXExpr *object, FilterXString *attr_name, FilterXExpr *new_value) { FilterXSetAttr *self = g_new0(FilterXSetAttr, 1); @@ -93,7 +93,9 @@ filterx_setattr_new(FilterXExpr *object, const gchar *attr_name, FilterXExpr *ne self->super.eval = _eval; self->super.free_fn = _free; self->object = object; - self->attr = filterx_string_new(attr_name, -1); + + self->attr = (FilterXObject *) attr_name; + self->new_value = new_value; self->super.ignore_falsy_result = TRUE; return &self->super; diff --git a/lib/filterx/expr-setattr.h b/lib/filterx/expr-setattr.h index 91a380e217..fac30396aa 100644 --- a/lib/filterx/expr-setattr.h +++ b/lib/filterx/expr-setattr.h @@ -24,8 +24,9 @@ #define FILTERX_SETATTR_H_INCLUDED #include "filterx/filterx-expr.h" +#include "filterx/object-string.h" -FilterXExpr *filterx_setattr_new(FilterXExpr *object, const gchar *attr_name, FilterXExpr *new_value); +FilterXExpr *filterx_setattr_new(FilterXExpr *object, FilterXString *attr_name, FilterXExpr *new_value); #endif diff --git a/lib/filterx/expr-variable.c b/lib/filterx/expr-variable.c index 297deef547..e26c0ad40c 100644 --- a/lib/filterx/expr-variable.c +++ b/lib/filterx/expr-variable.c @@ -27,6 +27,7 @@ #include "filterx/filterx-eval.h" #include "logmsg/logmsg.h" + typedef struct _FilterXVariableExpr { FilterXExpr super; @@ -164,7 +165,7 @@ _free(FilterXExpr *s) } static FilterXExpr * -filterx_variable_expr_new(const gchar *name, FilterXVariableType type) +filterx_variable_expr_new(FilterXString *name, FilterXVariableType type) { FilterXVariableExpr *self = g_new0(FilterXVariableExpr, 1); @@ -175,27 +176,21 @@ filterx_variable_expr_new(const gchar *name, FilterXVariableType type) self->super.assign = _assign; self->super.is_set = _isset; self->super.unset = _unset; - self->handle = filterx_scope_map_variable_to_handle(name, type); - if (type == FX_VAR_MESSAGE) - { - gchar *dollar_name = g_strdup_printf("$%s", name); - self->variable_name = filterx_string_new(dollar_name, -1); - g_free(dollar_name); - } - else - self->variable_name = filterx_string_new(name, -1); + + self->variable_name = (FilterXObject *) name; + self->handle = filterx_scope_map_variable_to_handle(filterx_string_get_value(self->variable_name, NULL), type); return &self->super; } FilterXExpr * -filterx_msg_variable_expr_new(const gchar *name) +filterx_msg_variable_expr_new(FilterXString *name) { return filterx_variable_expr_new(name, FX_VAR_MESSAGE); } FilterXExpr * -filterx_floating_variable_expr_new(const gchar *name) +filterx_floating_variable_expr_new(FilterXString *name) { return filterx_variable_expr_new(name, FX_VAR_FLOATING); } diff --git a/lib/filterx/expr-variable.h b/lib/filterx/expr-variable.h index d024505069..00ace103e4 100644 --- a/lib/filterx/expr-variable.h +++ b/lib/filterx/expr-variable.h @@ -24,9 +24,22 @@ #define FILTERX_EXPR_VARIABLE_H_INCLUDED #include "filterx/filterx-expr.h" +#include "filterx/filterx-config.h" +#include "filterx/object-string.h" +#include "cfg.h" -FilterXExpr *filterx_msg_variable_expr_new(const gchar *name); -FilterXExpr *filterx_floating_variable_expr_new(const gchar *name); +FilterXExpr *filterx_msg_variable_expr_new(FilterXString *name); +FilterXExpr *filterx_floating_variable_expr_new(FilterXString *name); void filterx_variable_expr_declare(FilterXExpr *s); +static inline FilterXString * +filterx_frozen_dollar_msg_varname(GlobalConfig *cfg, const gchar *name) +{ + gchar *dollar_name = g_strdup_printf("$%s", name); + FilterXString *dollar_name_obj = filterx_config_frozen_string(cfg, dollar_name); + g_free(dollar_name); + + return dollar_name_obj; +} + #endif diff --git a/lib/filterx/filterx-config.c b/lib/filterx/filterx-config.c index 92dd8e9ed7..d97f1f9fca 100644 --- a/lib/filterx/filterx-config.c +++ b/lib/filterx/filterx-config.c @@ -64,3 +64,12 @@ filterx_config_freeze_object(GlobalConfig *cfg, FilterXObject *object) g_ptr_array_add(fxc->frozen_objects, object); return object; } + +FilterXString * +filterx_config_frozen_string(GlobalConfig *cfg, const gchar *str) +{ + FilterXString *frozen_str = filterx_string_typed_new(str); + filterx_config_freeze_object(cfg, (FilterXObject *) frozen_str); + + return frozen_str; +} diff --git a/lib/filterx/filterx-config.h b/lib/filterx/filterx-config.h index 17dfb4d3ca..ed52dd3f58 100644 --- a/lib/filterx/filterx-config.h +++ b/lib/filterx/filterx-config.h @@ -25,6 +25,7 @@ #include "module-config.h" #include "filterx/filterx-object.h" +#include "filterx/object-string.h" typedef struct _FilterXConfig { @@ -34,5 +35,6 @@ typedef struct _FilterXConfig FilterXConfig *filterx_config_get(GlobalConfig *cfg); FilterXObject *filterx_config_freeze_object(GlobalConfig *cfg, FilterXObject *object); +FilterXString *filterx_config_frozen_string(GlobalConfig *cfg, const gchar *str); #endif diff --git a/lib/filterx/filterx-grammar.ym b/lib/filterx/filterx-grammar.ym index ddabcabc56..b7c8c2a292 100644 --- a/lib/filterx/filterx-grammar.ym +++ b/lib/filterx/filterx-grammar.ym @@ -66,12 +66,10 @@ construct_template_expr(LogTemplate *template) FilterXExpr *result; if (log_template_is_literal_string(template)) - result = filterx_literal_new( - filterx_config_freeze_object(configuration, - filterx_string_new(log_template_get_literal_value(template, NULL), -1))); + result = filterx_literal_new(filterx_config_freeze_object(configuration, filterx_string_new(log_template_get_literal_value(template, NULL), -1))); else if (log_template_is_trivial(template)) - result = filterx_msg_variable_expr_new( - log_msg_get_value_name(log_template_get_trivial_value_handle(template), NULL)); + result = filterx_msg_variable_expr_new(filterx_frozen_dollar_msg_varname(configuration, + log_msg_get_value_name(log_template_get_trivial_value_handle(template), NULL))); else result = filterx_template_new(log_template_ref(template)); log_template_unref(template); @@ -193,7 +191,7 @@ plus_assignment | expr '[' expr ']' KW_PLUS_ASSIGN expr { $$ = filterx_set_subscript_new(filterx_expr_ref($1), filterx_expr_ref($3), filterx_operator_plus_new(filterx_get_subscript_new($1, $3), $6)); } | expr '.' identifier KW_PLUS_ASSIGN expr { - $$ = filterx_setattr_new(filterx_expr_ref($1), $3, filterx_operator_plus_new(filterx_getattr_new($1, $3), $5)); + $$ = filterx_setattr_new(filterx_expr_ref($1), filterx_config_frozen_string(configuration, $3), filterx_operator_plus_new(filterx_getattr_new($1, filterx_config_frozen_string(configuration, $3)), $5)); free($3); } ; @@ -202,7 +200,7 @@ plus_assignment assignment /* TODO extract lvalues */ : variable KW_ASSIGN expr { $$ = filterx_assign_new($1, $3); } - | expr '.' identifier KW_ASSIGN expr { $$ = filterx_setattr_new($1, $3, $5); free($3); } + | expr '.' identifier KW_ASSIGN expr { $$ = filterx_setattr_new($1, filterx_config_frozen_string(configuration, $3), $5); free($3); } | expr '[' expr ']' KW_ASSIGN expr { $$ = filterx_set_subscript_new($1, $3, $6); } | expr '[' ']' KW_ASSIGN expr { $$ = filterx_set_subscript_new($1, NULL, $5); } | generator_assignment @@ -215,10 +213,10 @@ generator_assignment /* TODO extract lvalues */ : expr '.' identifier KW_ASSIGN expr_generator { - filterx_generator_set_fillable($5, filterx_getattr_new(filterx_expr_ref($1), $3)); + filterx_generator_set_fillable($5, filterx_getattr_new(filterx_expr_ref($1), filterx_config_frozen_string(configuration, $3))); $$ = filterx_compound_expr_new_va(TRUE, - filterx_setattr_new($1, $3, filterx_generator_create_container_new($5, $1)), + filterx_setattr_new($1, filterx_config_frozen_string(configuration, $3), filterx_generator_create_container_new($5, $1)), $5, NULL ); @@ -265,7 +263,7 @@ generator_assignment generator_plus_assignment : variable KW_PLUS_ASSIGN expr_generator { $$ = $3; filterx_generator_set_fillable($3, $1); } | expr '[' expr ']' KW_PLUS_ASSIGN expr_generator { $$ = $6; filterx_generator_set_fillable($6, filterx_get_subscript_new($1, $3)); } - | expr '.' identifier KW_PLUS_ASSIGN expr_generator { $$ = $5; filterx_generator_set_fillable($5, filterx_getattr_new($1, $3)); free($3);} + | expr '.' identifier KW_PLUS_ASSIGN expr_generator { $$ = $5; filterx_generator_set_fillable($5, filterx_getattr_new($1, filterx_config_frozen_string(configuration, $3))); free($3);} generator_casted_assignment /* TODO extract lvalues */ @@ -290,10 +288,10 @@ generator_casted_assignment FilterXExpr *func = filterx_function_lookup(configuration, $5, NULL, &error); CHECK_FUNCTION_ERROR(func, @5, $5, error); - filterx_generator_set_fillable($7, filterx_getattr_new(filterx_expr_ref($1), $3)); + filterx_generator_set_fillable($7, filterx_getattr_new(filterx_expr_ref($1), filterx_config_frozen_string(configuration, $3))); $$ = filterx_compound_expr_new_va(TRUE, - filterx_setattr_new($1, $3, func), + filterx_setattr_new($1, filterx_config_frozen_string(configuration, $3), func), $7, NULL ); @@ -343,7 +341,7 @@ expr | expr KW_OR expr { $$ = filterx_binary_or_new($1, $3); } | expr KW_AND expr { $$ = filterx_binary_and_new($1, $3); } /* TODO extract lvalues */ - | expr '.' identifier { $$ = filterx_getattr_new($1, $3); free($3); } + | expr '.' identifier { $$ = filterx_getattr_new($1, filterx_config_frozen_string(configuration, $3)); free($3); } | expr '[' expr ']' { $$ = filterx_get_subscript_new($1, $3); } | expr KW_TA_LT expr { $$ = filterx_comparison_new($1, $3, FCMPX_TYPE_AWARE | FCMPX_LT); } | expr KW_TA_LE expr { $$ = filterx_comparison_new($1, $3, FCMPX_TYPE_AWARE | FCMPX_LT | FCMPX_EQ); } @@ -467,13 +465,13 @@ literal_object ; variable - : '$' identifier { $$ = filterx_msg_variable_expr_new($2); free($2); } - | LL_MESSAGE_REF { $$ = filterx_msg_variable_expr_new($1); free($1); } + : '$' identifier { $$ = filterx_msg_variable_expr_new(filterx_frozen_dollar_msg_varname(configuration, $2)); free($2); } + | LL_MESSAGE_REF { $$ = filterx_msg_variable_expr_new(filterx_frozen_dollar_msg_varname(configuration, $1)); free($1); } | filterx_variable ; filterx_variable - : identifier { $$ = filterx_floating_variable_expr_new($1); free($1); } + : identifier { $$ = filterx_floating_variable_expr_new(filterx_config_frozen_string(configuration, $1)); free($1); } ; boolean diff --git a/lib/filterx/filterx-scope.c b/lib/filterx/filterx-scope.c index 09f5259cd7..6c95fd9b93 100644 --- a/lib/filterx/filterx-scope.c +++ b/lib/filterx/filterx-scope.c @@ -153,6 +153,9 @@ filterx_scope_is_dirty(FilterXScope *self) FilterXVariableHandle filterx_scope_map_variable_to_handle(const gchar *name, FilterXVariableType type) { + if (type == FX_VAR_MESSAGE) + name++; + NVHandle nv_handle = log_msg_get_value_handle(name); if (type == FX_VAR_MESSAGE) diff --git a/lib/filterx/object-string.c b/lib/filterx/object-string.c index 326e192b69..cae87db92f 100644 --- a/lib/filterx/object-string.c +++ b/lib/filterx/object-string.c @@ -29,12 +29,12 @@ #include "str-format.h" #include "str-utils.h" -typedef struct _FilterXString +struct _FilterXString { FilterXObject super; gsize str_len; gchar str[]; -} FilterXString; +}; /* NOTE: Consider using filterx_object_extract_string() to also support message_value. */ const gchar * @@ -142,18 +142,33 @@ _string_add(FilterXObject *s, FilterXObject *object) return filterx_string_new(buffer->str, buffer->len); } -FilterXObject * -filterx_string_new(const gchar *str, gssize str_len) +FilterXString * +_string_new(const gchar *str, gssize str_len) { if (str_len < 0) str_len = strlen(str); + FilterXString *self = g_malloc(sizeof(FilterXString) + str_len + 1); memset(self, 0, sizeof(FilterXString)); filterx_object_init_instance(&self->super, &FILTERX_TYPE_NAME(string)); + self->str_len = str_len; memcpy(self->str, str, str_len); self->str[str_len] = 0; - return &self->super; + + return self; +} + +FilterXObject * +filterx_string_new(const gchar *str, gssize str_len) +{ + return &_string_new(str, str_len)->super; +} + +FilterXString * +filterx_string_typed_new(const gchar *str) +{ + return _string_new(str, -1); } static inline gsize diff --git a/lib/filterx/object-string.h b/lib/filterx/object-string.h index 8839fd5547..c4fbbaa1e7 100644 --- a/lib/filterx/object-string.h +++ b/lib/filterx/object-string.h @@ -25,6 +25,8 @@ #include "filterx-object.h" +typedef struct _FilterXString FilterXString; + FILTERX_DECLARE_TYPE(string); FILTERX_DECLARE_TYPE(bytes); FILTERX_DECLARE_TYPE(protobuf); @@ -40,4 +42,6 @@ FilterXObject *filterx_string_new(const gchar *str, gssize str_len); FilterXObject *filterx_bytes_new(const gchar *str, gssize str_len); FilterXObject *filterx_protobuf_new(const gchar *str, gssize str_len); +FilterXString *filterx_string_typed_new(const gchar *str); + #endif diff --git a/lib/filterx/tests/test_expr_compound.c b/lib/filterx/tests/test_expr_compound.c index 025854cc92..e4c1c94369 100644 --- a/lib/filterx/tests/test_expr_compound.c +++ b/lib/filterx/tests/test_expr_compound.c @@ -38,7 +38,7 @@ FilterXExpr * _assert_assign_var(const char *var_name, FilterXExpr *value) { - FilterXExpr *control_variable = filterx_msg_variable_expr_new(var_name); + FilterXExpr *control_variable = filterx_msg_variable_expr_new(filterx_string_typed_new(var_name)); cr_assert(control_variable != NULL); return filterx_assign_new(control_variable, value); @@ -76,7 +76,7 @@ _assert_set_test_variable(const char *var_name, FilterXExpr *expr) FilterXObject * _assert_get_test_variable(const char *var_name) { - FilterXExpr *control_variable = filterx_msg_variable_expr_new(var_name); + FilterXExpr *control_variable = filterx_msg_variable_expr_new(filterx_string_typed_new(var_name)); cr_assert(control_variable != NULL); FilterXObject *result = filterx_expr_eval(control_variable); filterx_expr_unref(control_variable); diff --git a/lib/filterx/tests/test_expr_condition.c b/lib/filterx/tests/test_expr_condition.c index b2606840f4..5961c06916 100644 --- a/lib/filterx/tests/test_expr_condition.c +++ b/lib/filterx/tests/test_expr_condition.c @@ -62,7 +62,7 @@ _assert_cmp_string_to_filterx_object(const char *str, FilterXObject *obj) FilterXExpr * _assert_assign_var(const char *var_name, FilterXExpr *value) { - FilterXExpr *control_variable = filterx_msg_variable_expr_new(var_name); + FilterXExpr *control_variable = filterx_msg_variable_expr_new(filterx_string_typed_new(var_name)); cr_assert(control_variable != NULL); return filterx_assign_new(control_variable, value); @@ -85,7 +85,7 @@ _assert_set_test_variable(const char *var_name, FilterXExpr *expr) FilterXObject * _assert_get_test_variable(const char *var_name) { - FilterXExpr *control_variable = filterx_msg_variable_expr_new(var_name); + FilterXExpr *control_variable = filterx_msg_variable_expr_new(filterx_string_typed_new(var_name)); cr_assert(control_variable != NULL); FilterXObject *result = filterx_expr_eval(control_variable); filterx_expr_unref(control_variable); diff --git a/lib/filterx/tests/test_filterx_expr.c b/lib/filterx/tests/test_filterx_expr.c index f2ce59ae9b..c08d3facbc 100644 --- a/lib/filterx/tests/test_filterx_expr.c +++ b/lib/filterx/tests/test_filterx_expr.c @@ -304,7 +304,7 @@ Test(filterx_expr, test_filterx_dict_merge) Test(filterx_expr, test_filterx_assign) { - FilterXExpr *result_var = filterx_msg_variable_expr_new("$result-var"); + FilterXExpr *result_var = filterx_msg_variable_expr_new(filterx_string_typed_new("$result-var")); cr_assert(result_var != NULL); FilterXExpr *assign = filterx_assign_new(result_var, filterx_literal_new(filterx_string_new("foobar", -1))); @@ -333,7 +333,8 @@ Test(filterx_expr, test_filterx_setattr) FilterXObject *json = filterx_json_object_new_empty(); FilterXExpr *fillable = filterx_literal_new(json); - FilterXExpr *setattr = filterx_setattr_new(fillable, "foo", filterx_literal_new(filterx_string_new("bar", -1))); + FilterXExpr *setattr = filterx_setattr_new(fillable, filterx_string_typed_new("foo"), + filterx_literal_new(filterx_string_new("bar", -1))); cr_assert_not_null(setattr); FilterXObject *res = filterx_expr_eval(setattr); @@ -387,7 +388,7 @@ Test(filterx_expr, test_filterx_readonly) FilterXExpr *setattr = filterx_setattr_new(filterx_expr_ref(literal), - "bar", + filterx_string_typed_new("bar"), filterx_literal_new(filterx_object_ref(foo))); cr_assert_not(filterx_expr_eval(setattr)); cr_assert(strstr(filterx_eval_get_last_error(), "readonly")); @@ -404,7 +405,7 @@ Test(filterx_expr, test_filterx_readonly) filterx_expr_unref(set_subscript); - FilterXExpr *getattr = filterx_getattr_new(filterx_expr_ref(literal), "foo"); + FilterXExpr *getattr = filterx_getattr_new(filterx_expr_ref(literal), filterx_string_typed_new("foo")); cr_assert_not(filterx_expr_unset(getattr)); cr_assert(strstr(filterx_eval_get_last_error(), "readonly")); filterx_eval_clear_errors(); @@ -419,8 +420,9 @@ Test(filterx_expr, test_filterx_readonly) filterx_expr_unref(get_subscript); - FilterXExpr *inner = filterx_setattr_new(filterx_getattr_new(filterx_expr_ref(literal), "foo"), - "bar", + FilterXExpr *inner = filterx_setattr_new(filterx_getattr_new(filterx_expr_ref(literal), + filterx_string_typed_new("foo")), + filterx_string_typed_new("bar"), filterx_literal_new(filterx_object_ref(bar))); cr_assert_not(filterx_expr_eval(inner)); cr_assert(strstr(filterx_eval_get_last_error(), "readonly"));