mirror of
https://github.com/falcosecurity/falco.git
synced 2025-07-16 15:51:55 +00:00
Expand in
relational expressions
For example, `a.b in [1, 2]` is expanded to `a.b = 1 or a.b = 2`. This is done over the AST, not filter text.
This commit is contained in:
parent
3dab9edc9d
commit
79cdf31aa7
@ -15,12 +15,12 @@ function error_exit_bad
|
|||||||
|
|
||||||
function good
|
function good
|
||||||
{
|
{
|
||||||
lua test.lua "$1" || error_exit_good "$1"
|
lua test.lua "$1" 2> /dev/null || error_exit_good "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
function bad
|
function bad
|
||||||
{
|
{
|
||||||
lua test.lua "$1" && error_exit_bad "$1"
|
lua test.lua "$1" 2> /dev/null && error_exit_bad "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Filters
|
# Filters
|
||||||
@ -47,7 +47,6 @@ good "a.b = 'bla'"
|
|||||||
good "a.b = not"
|
good "a.b = not"
|
||||||
good "a.b contains bla"
|
good "a.b contains bla"
|
||||||
good "a.b icontains 'bla'"
|
good "a.b icontains 'bla'"
|
||||||
good "a.g in ()"
|
|
||||||
good "a.g in (1, 'a', b)"
|
good "a.g in (1, 'a', b)"
|
||||||
good "a.g in ( 1 ,, , b)"
|
good "a.g in ( 1 ,, , b)"
|
||||||
good "evt.dir=> and fd.name=*.log"
|
good "evt.dir=> and fd.name=*.log"
|
||||||
@ -55,6 +54,7 @@ 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"
|
||||||
|
|
||||||
|
bad "a.g in ()"
|
||||||
bad "(a.b = 1"
|
bad "(a.b = 1"
|
||||||
# Macros
|
# Macros
|
||||||
|
|
||||||
@ -66,4 +66,6 @@ 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:"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "All tests passed."
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -237,6 +237,74 @@ local G = {
|
|||||||
OneWord = V"Name" + V"Number" + V"String" + P(1);
|
OneWord = V"Name" + V"Number" + V"String" + P(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function map(f, arr)
|
||||||
|
local res = {}
|
||||||
|
for i,v in ipairs(arr) do
|
||||||
|
res[i] = f(v)
|
||||||
|
end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
function foldr(f, acc, arr)
|
||||||
|
for i,v in pairs(arr) do
|
||||||
|
acc = f(acc, v)
|
||||||
|
end
|
||||||
|
return acc
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Traverses the AST and replaces `in` relational expressions with a sequence of ORs.
|
||||||
|
|
||||||
|
For example, `a.b in [1, 2]` is expanded to `a.b = 1 or a.b = 2` (in ASTs)
|
||||||
|
]]--
|
||||||
|
function expand_in(node)
|
||||||
|
local t = node.type
|
||||||
|
|
||||||
|
if t == "Filter" then
|
||||||
|
expand_in(node.value)
|
||||||
|
|
||||||
|
elseif t == "UnaryBoolOp" then
|
||||||
|
expand_in(node.argument)
|
||||||
|
|
||||||
|
elseif t == "BinaryBoolOp" then
|
||||||
|
expand_in(node.left)
|
||||||
|
expand_in(node.right)
|
||||||
|
|
||||||
|
elseif t == "BinaryRelOp" and node.operator == "in" then
|
||||||
|
if (table.maxn(node.right.elements) == 0) then
|
||||||
|
error ("In list with zero elements")
|
||||||
|
end
|
||||||
|
|
||||||
|
local mapper = function(element)
|
||||||
|
return {
|
||||||
|
type = "BinaryRelOp",
|
||||||
|
operator = "eq",
|
||||||
|
left = node.left,
|
||||||
|
right = element
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local equalities = map(mapper, node.right.elements)
|
||||||
|
local lasteq = equalities[table.maxn(equalities)]
|
||||||
|
equalities[table.maxn(equalities)] = nil
|
||||||
|
|
||||||
|
local folder = function(left, right)
|
||||||
|
return {
|
||||||
|
type = "BinaryBoolOp",
|
||||||
|
operator = "or",
|
||||||
|
left = left,
|
||||||
|
right = right
|
||||||
|
}
|
||||||
|
end
|
||||||
|
lasteq = foldr(folder, lasteq, equalities)
|
||||||
|
|
||||||
|
node.type=lasteq.type
|
||||||
|
node.operator=lasteq.operator
|
||||||
|
node.left=lasteq.left
|
||||||
|
node.right=lasteq.right
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function print_ast(node, level)
|
function print_ast(node, level)
|
||||||
local t = node.type
|
local t = node.type
|
||||||
local prefix = string.rep(" ", level*2)
|
local prefix = string.rep(" ", level*2)
|
||||||
@ -276,6 +344,10 @@ function parser.parse (subject)
|
|||||||
local errorinfo = { subject = subject }
|
local errorinfo = { subject = subject }
|
||||||
lpeg.setmaxstack(1000)
|
lpeg.setmaxstack(1000)
|
||||||
local ast, error_msg = lpeg.match(G, subject, nil, errorinfo)
|
local ast, error_msg = lpeg.match(G, subject, nil, errorinfo)
|
||||||
|
if (error_msg) then
|
||||||
|
return ast, error_msg
|
||||||
|
end
|
||||||
|
expand_in(ast)
|
||||||
return ast, error_msg
|
return ast, error_msg
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user