mirror of
https://github.com/falcosecurity/falco.git
synced 2025-08-09 01:58:13 +00:00
Grammar: support function-call syntax in outputs
This change adds syntax support for function call outputs. For example: ... | syslog(evt, WARN) Regular outputs are still allowed and parsed in the same way.
This commit is contained in:
parent
733548b80b
commit
6569f0372d
@ -167,6 +167,10 @@ local function outputformat (format)
|
|||||||
return {type = "OutputFormat", value = format}
|
return {type = "OutputFormat", value = format}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function functioncall (name, args)
|
||||||
|
return {type = "FunctionCall", name = name, arguments = args}
|
||||||
|
end
|
||||||
|
|
||||||
local function rule(filter, output)
|
local function rule(filter, output)
|
||||||
if not output then
|
if not output then
|
||||||
output = outputformat("")
|
output = outputformat("")
|
||||||
@ -182,7 +186,7 @@ local G = {
|
|||||||
-- Grammar
|
-- Grammar
|
||||||
Comment = P"#" * P(1)^0;
|
Comment = P"#" * P(1)^0;
|
||||||
|
|
||||||
Rule = V"Filter" / filter * ((V"Skip" * V"Pipe" * V"Skip" * (P(1)^0 / outputformat) )^-1 );
|
Rule = V"Filter" / filter * ((V"Skip" * V"Pipe" * V"Skip" * V"Output")^-1 );
|
||||||
|
|
||||||
Filter = V"OrExpression";
|
Filter = V"OrExpression";
|
||||||
OrExpression =
|
OrExpression =
|
||||||
@ -212,6 +216,9 @@ local G = {
|
|||||||
|
|
||||||
MacroDef = (C(V"Macro") * V"Skip" * V"Colon" * (V"Filter"));
|
MacroDef = (C(V"Macro") * V"Skip" * V"Colon" * (V"Filter"));
|
||||||
|
|
||||||
|
FuncArgs = symb("(") * list(V"Value", symb(",")) * symb(")");
|
||||||
|
Output = ((V"Name" * V"FuncArgs") / functioncall) + P(1)^0 / outputformat;
|
||||||
|
|
||||||
-- Terminals
|
-- Terminals
|
||||||
Value = terminal "Number" + terminal "String" + terminal "BareString";
|
Value = terminal "Number" + terminal "String" + terminal "BareString";
|
||||||
|
|
||||||
@ -448,8 +455,17 @@ function print_ast(ast, level)
|
|||||||
if t == "Rule" then
|
if t == "Rule" then
|
||||||
print_ast(ast.filter, level)
|
print_ast(ast.filter, level)
|
||||||
if (ast.output) then
|
if (ast.output) then
|
||||||
print(prefix.."| "..ast.output.value)
|
print(prefix.."| ")
|
||||||
|
print_ast(ast.output)
|
||||||
end
|
end
|
||||||
|
elseif t == "OutputFormat" then
|
||||||
|
print(ast.value)
|
||||||
|
|
||||||
|
elseif t == "FunctionCall" then
|
||||||
|
print(ast.name .. "(" )
|
||||||
|
print_ast(ast.arguments)
|
||||||
|
print(")")
|
||||||
|
|
||||||
elseif t == "Filter" then
|
elseif t == "Filter" then
|
||||||
print_ast(ast.value, level)
|
print_ast(ast.value, level)
|
||||||
|
|
||||||
@ -463,7 +479,6 @@ function print_ast(ast, level)
|
|||||||
print_ast(ast.argument, level)
|
print_ast(ast.argument, level)
|
||||||
|
|
||||||
elseif t == "List" then
|
elseif t == "List" then
|
||||||
print(prefix.. "List: ")
|
|
||||||
for i, v in ipairs(ast.elements) do
|
for i, v in ipairs(ast.elements) do
|
||||||
print_ast(v, level)
|
print_ast(v, level)
|
||||||
end
|
end
|
||||||
|
@ -57,8 +57,6 @@ good "evt.dir=> and fd.name=*.log"
|
|||||||
good "evt.dir=> and fd.name=/var/log/httpd.log"
|
good "evt.dir=> and fd.name=/var/log/httpd.log"
|
||||||
good "a.g in (1, 'a', b.c)"
|
good "a.g in (1, 'a', b.c)"
|
||||||
good "a.b = a.a"
|
good "a.b = a.a"
|
||||||
good "a.b = a.a |"
|
|
||||||
good "a.b = a.a | %evt.type %fd.num blabla"
|
|
||||||
|
|
||||||
good "evt.arg[0] contains /bin"
|
good "evt.arg[0] contains /bin"
|
||||||
bad "evt.arg[a] contains /bin"
|
bad "evt.arg[a] contains /bin"
|
||||||
@ -67,9 +65,9 @@ bad "evt.arg[] contains /bin"
|
|||||||
bad "a.g in ()"
|
bad "a.g in ()"
|
||||||
bad "a.b = b = 1"
|
bad "a.b = b = 1"
|
||||||
bad "(a.b = 1"
|
bad "(a.b = 1"
|
||||||
bad " | %a.b"
|
|
||||||
# Macros
|
|
||||||
|
|
||||||
|
|
||||||
|
# Macros
|
||||||
good "a: a.b exists"
|
good "a: a.b exists"
|
||||||
good "a: b and c"
|
good "a: b and c"
|
||||||
good "a: b"
|
good "a: b"
|
||||||
@ -77,9 +75,19 @@ good "a : b"
|
|||||||
good "a : evt.dir=>"
|
good "a : evt.dir=>"
|
||||||
good "inbound: (syscall.type=listen and evt.dir='>') or (syscall.type=accept and evt.dir='<')"
|
good "inbound: (syscall.type=listen and evt.dir='>') or (syscall.type=accept and evt.dir='<')"
|
||||||
bad "a:"
|
bad "a:"
|
||||||
bad "a : b | bla"
|
|
||||||
bad "b and d"
|
bad "b and d"
|
||||||
|
|
||||||
|
# Outputs
|
||||||
|
good "a.b = a.a |"
|
||||||
|
good "a.b = a.a | %evt.type %fd.num blabla"
|
||||||
|
good "a.b = a.a | blabla (%evt.type %fd.num)"
|
||||||
|
good "a.b = a.a | f(evt)"
|
||||||
|
good "a.b = a.a | f()"
|
||||||
|
bad "a.b = a.a | f() evt"
|
||||||
|
|
||||||
|
bad "a : b | bla"
|
||||||
|
bad " | %a.b"
|
||||||
|
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "All tests passed."
|
echo "All tests passed."
|
||||||
|
Loading…
Reference in New Issue
Block a user