From b3cf652abce4aeae65c33d87745bc004b8d45a38 Mon Sep 17 00:00:00 2001 From: shifter Date: Wed, 7 Aug 2024 13:24:42 +0200 Subject: [PATCH 1/6] cfg-grammar: fix precedence for KW_PLUS_ASSIGN Signed-off-by: shifter --- lib/cfg-grammar.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cfg-grammar.y b/lib/cfg-grammar.y index 1a99cc4493..69ed8ad02e 100644 --- a/lib/cfg-grammar.y +++ b/lib/cfg-grammar.y @@ -206,13 +206,13 @@ main_location_print (FILE *yyo, YYLTYPE const * const yylocp) /* operators in the filter language, the order of this determines precedence */ %right KW_ASSIGN 9000 +%right KW_PLUS_ASSIGN 9001 %right '?' ':' %right KW_NULL_COALESCING %left KW_OR 9010 %left KW_AND 9020 %left KW_STR_EQ 9030 KW_STR_NE 9031, KW_TA_EQ 9032, KW_TA_NE 9033, KW_TAV_EQ 9034, KW_TAV_NE 9035 %left KW_STR_LT 9040, KW_STR_LE 9041, KW_STR_GE, 9042 KW_STR_GT, 9043, KW_TA_LT 9044, KW_TA_LE 9045, KW_TA_GE 9046, KW_TA_GT 9047 -%right KW_PLUS_ASSIGN 9050 %left KW_REGEXP_MATCH 9060 %left '+' '-' From 405203495f7ba628d3251a3b8a82012e53a39f37 Mon Sep 17 00:00:00 2001 From: shifter Date: Wed, 7 Aug 2024 13:27:14 +0200 Subject: [PATCH 2/6] cfg-grammar: fix precedence of KW_REGEXP_MATCH Signed-off-by: shifter --- lib/cfg-grammar.y | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/cfg-grammar.y b/lib/cfg-grammar.y index 69ed8ad02e..f4ed0785e6 100644 --- a/lib/cfg-grammar.y +++ b/lib/cfg-grammar.y @@ -211,9 +211,8 @@ main_location_print (FILE *yyo, YYLTYPE const * const yylocp) %right KW_NULL_COALESCING %left KW_OR 9010 %left KW_AND 9020 -%left KW_STR_EQ 9030 KW_STR_NE 9031, KW_TA_EQ 9032, KW_TA_NE 9033, KW_TAV_EQ 9034, KW_TAV_NE 9035 +%left KW_STR_EQ 9030 KW_STR_NE 9031, KW_TA_EQ 9032, KW_TA_NE 9033, KW_TAV_EQ 9034, KW_TAV_NE 9035, KW_REGEXP_MATCH 9036 %left KW_STR_LT 9040, KW_STR_LE 9041, KW_STR_GE, 9042 KW_STR_GT, 9043, KW_TA_LT 9044, KW_TA_LE 9045, KW_TA_GE 9046, KW_TA_GT 9047 -%left KW_REGEXP_MATCH 9060 %left '+' '-' %left '*' From 971a3ccbbeae9b7b4135bdc4083ad346d587e002 Mon Sep 17 00:00:00 2001 From: shifter Date: Wed, 7 Aug 2024 10:01:04 +0200 Subject: [PATCH 3/6] filterx: add regexp nomatch keyword definition to lexer Signed-off-by: shifter --- lib/cfg-grammar.y | 2 +- lib/cfg-lex.l | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/cfg-grammar.y b/lib/cfg-grammar.y index f4ed0785e6..d5406937ee 100644 --- a/lib/cfg-grammar.y +++ b/lib/cfg-grammar.y @@ -211,7 +211,7 @@ main_location_print (FILE *yyo, YYLTYPE const * const yylocp) %right KW_NULL_COALESCING %left KW_OR 9010 %left KW_AND 9020 -%left KW_STR_EQ 9030 KW_STR_NE 9031, KW_TA_EQ 9032, KW_TA_NE 9033, KW_TAV_EQ 9034, KW_TAV_NE 9035, KW_REGEXP_MATCH 9036 +%left KW_STR_EQ 9030 KW_STR_NE 9031, KW_TA_EQ 9032, KW_TA_NE 9033, KW_TAV_EQ 9034, KW_TAV_NE 9035, KW_REGEXP_MATCH 9036, KW_REGEXP_NOMATCH 9037 %left KW_STR_LT 9040, KW_STR_LE 9041, KW_STR_GE, 9042 KW_STR_GT, 9043, KW_TA_LT 9044, KW_TA_LE 9045, KW_TA_GE 9046, KW_TA_GT 9047 %left '+' '-' diff --git a/lib/cfg-lex.l b/lib/cfg-lex.l index d80bd764c9..14de8e338f 100644 --- a/lib/cfg-lex.l +++ b/lib/cfg-lex.l @@ -319,6 +319,7 @@ filterx_word [^ \#'"/\(\)\{\}\[\]\\;\r\n\t,|\.@:] !== { return KW_TAV_NE; } \+= { return KW_PLUS_ASSIGN; } =~ { return KW_REGEXP_MATCH; } +!~ { return KW_REGEXP_NOMATCH; } \?\? { return KW_NULL_COALESCING; } (-|\+)?{digit}+\.{digit}+ { yylval->fnum = strtod(yytext, NULL); return LL_FLOAT; } From 8666a107f1fd2588f0fed5c82665f4981f8598a4 Mon Sep 17 00:00:00 2001 From: shifter Date: Wed, 7 Aug 2024 10:01:59 +0200 Subject: [PATCH 4/6] filterx: extend expr-regexp match function with an invert option Signed-off-by: shifter --- lib/filterx/expr-regexp.c | 10 +++++++++- lib/filterx/expr-regexp.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/filterx/expr-regexp.c b/lib/filterx/expr-regexp.c index 816d0cad68..7e888e123e 100644 --- a/lib/filterx/expr-regexp.c +++ b/lib/filterx/expr-regexp.c @@ -282,6 +282,7 @@ typedef struct FilterXExprRegexpMatch_ FilterXExpr super; FilterXExpr *lhs; pcre2_code_8 *pattern; + gboolean invert; } FilterXExprRegexpMatch; static FilterXObject * @@ -300,7 +301,7 @@ _regexp_match_eval(FilterXExpr *s) goto exit; } - result = filterx_boolean_new(matched); + result = filterx_boolean_new(matched != self->invert); exit: _state_cleanup(&state); @@ -339,6 +340,13 @@ filterx_expr_regexp_match_new(FilterXExpr *lhs, const gchar *pattern) return &self->super; } +FilterXExpr * +filterx_expr_regexp_nomatch_new(FilterXExpr *lhs, const gchar *pattern) +{ + FilterXExprRegexpMatch *self = (FilterXExprRegexpMatch *)filterx_expr_regexp_match_new(lhs, pattern); + self->invert = TRUE; + return &self->super; +} typedef struct FilterXExprRegexpSearchGenerator_ { diff --git a/lib/filterx/expr-regexp.h b/lib/filterx/expr-regexp.h index d8b7458a4f..30d49a9c2b 100644 --- a/lib/filterx/expr-regexp.h +++ b/lib/filterx/expr-regexp.h @@ -44,6 +44,7 @@ typedef struct FilterXFuncRegexpSubstOpts_ } FilterXFuncRegexpSubstOpts; FilterXExpr *filterx_expr_regexp_match_new(FilterXExpr *lhs, const gchar *pattern); +FilterXExpr *filterx_expr_regexp_nomatch_new(FilterXExpr *lhs, const gchar *pattern); FilterXExpr *filterx_expr_regexp_search_generator_new(FilterXExpr *lhs, const gchar *pattern); FilterXFunction *filterx_function_regexp_subst_new(const gchar *function_name, FilterXFunctionArgs *args, GError **error); From b19e54c17ff9b838c05859474316e7cfc7f6366a Mon Sep 17 00:00:00 2001 From: shifter Date: Wed, 7 Aug 2024 10:03:06 +0200 Subject: [PATCH 5/6] filterx: grammar defintion for regex nomatch keyword Signed-off-by: shifter --- lib/filterx/filterx-grammar.ym | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/filterx/filterx-grammar.ym b/lib/filterx/filterx-grammar.ym index 4266425af9..1ea790be6c 100644 --- a/lib/filterx/filterx-grammar.ym +++ b/lib/filterx/filterx-grammar.ym @@ -511,6 +511,7 @@ regexp_search regexp_match : expr KW_REGEXP_MATCH string { $$ = filterx_expr_regexp_match_new($1, $3); free($3); } + | expr KW_REGEXP_NOMATCH string { $$ = filterx_expr_regexp_nomatch_new($1, $3); free($3); } ; conditional From 9d12ada90e83b9839e596a7be94a516dfccd4678 Mon Sep 17 00:00:00 2001 From: shifter Date: Wed, 7 Aug 2024 10:03:47 +0200 Subject: [PATCH 6/6] filterx: add light tests for expr nomatch operator Signed-off-by: shifter --- .../functional_tests/filterx/test_filterx.py | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/light/functional_tests/filterx/test_filterx.py b/tests/light/functional_tests/filterx/test_filterx.py index f8e96cd9d4..a26c94cefa 100644 --- a/tests/light/functional_tests/filterx/test_filterx.py +++ b/tests/light/functional_tests/filterx/test_filterx.py @@ -1245,6 +1245,32 @@ def test_regexp_match(config, syslog_ng): assert file_true.read_log() == "success\n" +def test_regexp_nomatch(config, syslog_ng): + (file_true, file_false) = create_config( + config, r""" + $MSG = json(); + $MSG.match = ${values.str} !~ /string/; + $MSG.match_any = ${values.str} !~ /.*/; + $MSG.nomatch = ${values.str} !~ /wrong/; + $MSG.match_inverse = not (${values.str} !~ /.*/); + $MSG.nomatch_inverse = not (${values.str} !~ /foobar/); +""", + ) + syslog_ng.start(config) + + exp = ( + r"""{"match":false,""" + r""""match_any":false,""" + r""""nomatch":true,""" + r""""match_inverse":true,""" + r""""nomatch_inverse":false}""" + "\n" + ) + + assert file_true.get_stats()["processed"] == 1 + assert "processed" not in file_false.get_stats() + assert file_true.read_log() == exp + + def test_regexp_match_error_in_pattern(config, syslog_ng): _ = create_config( config, r"""