-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
lib/filterx: add startswith / endswith functions #277
Conversation
OverOrion
commented
Sep 6, 2024
0b96fb7
to
e3bf29f
Compare
Signed-off-by: Szilard Parrag <[email protected]>
Signed-off-by: Szilard Parrag <[email protected]>
Signed-off-by: Szilard Parrag <[email protected]>
Signed-off-by: Szilard Parrag <[email protected]>
Signed-off-by: Szilard Parrag <[email protected]>
e3bf29f
to
2b0315b
Compare
@@ -33,6 +33,7 @@ | |||
|
|||
|
|||
#define FILTERX_FUNC_STARTSWITH_USAGE "Usage: startswith(my_string, my_prefix)" | |||
#define FILTERX_FUNC_ENDSWITH_USAGE "Usage: endswith(my_string, my_prefix)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: "my_suffix"
FilterXExpr *needle_expr = filterx_function_args_get_expr(args, 1); | ||
if (!filterx_expr_is_literal(needle_expr)) | ||
{ | ||
needle->expr = filterx_expr_ref(needle_expr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this ref is unnecessary.
gsize needle_str_len; | ||
const gchar *needle_str = filterx_function_args_get_literal_string(args, 1, &needle_str_len); | ||
if (!needle_str) | ||
return FALSE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please set an error message here.
return FALSE; | ||
} | ||
if (!ignorecase) | ||
*needle_str = g_strdup(needle_str_res); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess that this strdup()
is here because this way the function always returns a string that needs to be freed, but if ignorecase
is not set, this is basically an unnecessary copy. Can we solve this somehow? Maybe we can return whether the returned string needs freeing or not. Or we could check for self->ignorecase
on the call site to decide whether we need to free or not (the check could even be extracted to a function, but it might be overkill).
Same for haystack.
filterx_expr_unref(self->haystack); | ||
if (self->needle.expr) | ||
filterx_expr_unref(self->needle.expr); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Who frees self->needle.literal.str
?
typedef struct _FilterXExprOrLiteral | ||
{ | ||
FilterXExpr *expr; | ||
struct | ||
{ | ||
gchar *str; | ||
gssize str_len; | ||
} literal; | ||
} FilterXExprOrLiteral; | ||
|
||
typedef struct _FilterXFuncStartsWith | ||
{ | ||
FilterXFunction super; | ||
FilterXExpr *haystack; | ||
FilterXExprOrLiteral needle; | ||
gsize needle_len; | ||
gboolean ignore_case; | ||
} FilterXFuncStartsWith; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These could be "private" == defined in the .c
file.
def test_startswith_literal(config, syslog_ng): | ||
(file_true, file_false) = create_config( | ||
config, r""" | ||
if (startswith($MSG, "foo")) | ||
{ | ||
$MSG = json(); | ||
$MSG.startswith_foo = true; | ||
}; | ||
""", msg="foo", | ||
) | ||
syslog_ng.start(config) | ||
|
||
assert file_true.get_stats()["processed"] == 1 | ||
assert "processed" not in file_false.get_stats() | ||
assert file_true.read_log() == '{"startswith_foo":true}\n' | ||
|
||
|
||
def test_startswith_expr_ignorecase(config, syslog_ng): | ||
(file_true, file_false) = create_config( | ||
config, r""" | ||
prefix = "FoO"; | ||
if (startswith($MSG, prefix, ignorecase=true)) | ||
{ | ||
$MSG = json(); | ||
$MSG.startswith_foo_ignorecase = true; | ||
}; | ||
""", msg="foo", | ||
) | ||
syslog_ng.start(config) | ||
|
||
assert file_true.get_stats()["processed"] == 1 | ||
assert "processed" not in file_false.get_stats() | ||
assert file_true.read_log() == '{"startswith_foo_ignorecase":true}\n' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[optional]
Having 2 (4 with endswith) testcases is cleaner, but takes longer time to execute, as we start syslog-ng multiple times, and it has an overhead.
Could you merge the 4 into one testcase, please?