diff --git a/lib/filterx/expr-message-ref.c b/lib/filterx/expr-message-ref.c index 251383af4a..5d01f62b1f 100644 --- a/lib/filterx/expr-message-ref.c +++ b/lib/filterx/expr-message-ref.c @@ -31,27 +31,39 @@ typedef struct _FilterXMessageRefExpr NVHandle handle; } FilterXMessageRefExpr; +static FilterXObject * +_pull_variable_from_message(FilterXMessageRefExpr *self, FilterXEvalContext *context, LogMessage *msg) +{ + gssize value_len; + LogMessageValueType t; + const gchar *value = log_msg_get_value_if_set_with_type(msg, self->handle, &value_len, &t); + if (!value) + return NULL; + + FilterXObject *msg_ref = filterx_message_value_new_borrowed(value, value_len, t); + filterx_scope_register_variable(context->scope, self->handle, FALSE, msg_ref); + return msg_ref; +} + +/* NOTE: unset on a variable that only exists in the LogMessage, without making the message writable */ +static void +_whiteout_variable(FilterXMessageRefExpr *self, FilterXEvalContext *context) +{ + filterx_scope_register_variable(context->scope, self->handle, FALSE, NULL); +} + static FilterXObject * _eval(FilterXExpr *s) { FilterXMessageRefExpr *self = (FilterXMessageRefExpr *) s; FilterXEvalContext *context = filterx_eval_get_context(); - LogMessage *msg = context->msgs[0]; FilterXVariable *variable; variable = filterx_scope_lookup_variable(context->scope, self->handle); if (variable) return filterx_variable_get_value(variable); - gssize value_len; - LogMessageValueType t; - const gchar *value = log_msg_get_value_if_set_with_type(msg, self->handle, &value_len, &t); - if (!value) - return NULL; - - FilterXObject *msg_ref = filterx_message_value_new_borrowed(value, value_len, t); - variable = filterx_scope_register_variable(context->scope, self->handle, FALSE, msg_ref); - return msg_ref; + return _pull_variable_from_message(self, context, context->msgs[0]); } static void @@ -89,6 +101,41 @@ _assign(FilterXExpr *s, FilterXObject *new_value) return TRUE; } +static gboolean +_isset(FilterXExpr *s) +{ + FilterXMessageRefExpr *self = (FilterXMessageRefExpr *) s; + FilterXScope *scope = filterx_eval_get_scope(); + + FilterXVariable *variable = filterx_scope_lookup_variable(scope, self->handle); + if (variable) + return filterx_variable_is_set(variable); + + FilterXEvalContext *context = filterx_eval_get_context(); + LogMessage *msg = context->msgs[0]; + return log_msg_is_value_set(msg, self->handle); +} + +static gboolean +_unset(FilterXExpr *s) +{ + FilterXMessageRefExpr *self = (FilterXMessageRefExpr *) s; + FilterXEvalContext *context = filterx_eval_get_context(); + + FilterXVariable *variable = filterx_scope_lookup_variable(context->scope, self->handle); + if (variable) + { + filterx_variable_unset_value(variable); + return TRUE; + } + + LogMessage *msg = context->msgs[0]; + if (log_msg_is_value_set(msg, self->handle)) + _whiteout_variable(self, context); + + return TRUE; +} + static void _free(FilterXExpr *s) { @@ -104,6 +151,8 @@ filterx_message_ref_expr_new(NVHandle handle) self->super.eval = _eval; self->super._update_repr = _update_repr; self->super.assign = _assign; + self->super.isset = _isset; + self->super.unset = _unset; self->super.free_fn = _free; self->handle = handle; return &self->super;