mirror of
https://github.com/falcosecurity/falco.git
synced 2025-09-14 05:51:43 +00:00
Move compiler state and AST grafting to rule_loader.lua
This is needed so that rule_loader (which should be renamed in a later pass..) can tag filters with their index.
This commit is contained in:
@@ -341,7 +341,6 @@ function expand_macros(node, defs, changed)
|
|||||||
elseif node.type == "Filter" then
|
elseif node.type == "Filter" then
|
||||||
if (node.value.type == "Macro") then
|
if (node.value.type == "Macro") then
|
||||||
if (defs[node.value.value] == nil) then
|
if (defs[node.value.value] == nil) then
|
||||||
tostring = require 'ml'.tstring
|
|
||||||
error("Undefined macro '".. node.value.value .. "' used in filter.")
|
error("Undefined macro '".. node.value.value .. "' used in filter.")
|
||||||
end
|
end
|
||||||
node.value = defs[node.value.value]
|
node.value = defs[node.value.value]
|
||||||
@@ -445,7 +444,7 @@ function print_ast(node, level)
|
|||||||
elseif t == "MacroDef" then
|
elseif t == "MacroDef" then
|
||||||
-- don't print for now
|
-- don't print for now
|
||||||
else
|
else
|
||||||
error ("Unexpected type: "..t)
|
error ("Unexpected type in print_ast: "..t)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
compiler.parser.print_ast = print_ast
|
compiler.parser.print_ast = print_ast
|
||||||
@@ -463,22 +462,9 @@ end
|
|||||||
|
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
Sets up compiler state and returns it.
|
Compiles a single line from a digwatch ruleset and updates the passed-in macros table. Returns the AST of the line.
|
||||||
|
|
||||||
This is an opaque blob that is passed into subsequent compiler calls and
|
|
||||||
should not be modified by the client.
|
|
||||||
|
|
||||||
It holds state such as macro definitions that must be kept across calls
|
|
||||||
to the line-oriented compiler.
|
|
||||||
--]]
|
--]]
|
||||||
function compiler.init()
|
function compiler.compile_line(line, macro_defs)
|
||||||
return {macros={}, filter_ast=nil}
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[
|
|
||||||
Compiles a single line from a digwatch ruleset and updates the passed-in state object. Returns the AST of the line.
|
|
||||||
--]]
|
|
||||||
function compiler.compile_line(line, state)
|
|
||||||
local ast, error_msg = compiler.parser.parse_line(line)
|
local ast, error_msg = compiler.parser.parse_line(line)
|
||||||
|
|
||||||
if (error_msg) then
|
if (error_msg) then
|
||||||
@@ -504,7 +490,7 @@ function compiler.compile_line(line, state)
|
|||||||
end
|
end
|
||||||
|
|
||||||
for m, _ in pairs(macros) do
|
for m, _ in pairs(macros) do
|
||||||
if state.macros[m] == nil then
|
if macros[m] == nil then
|
||||||
error ("Undefined macro '"..m.."' used in '"..line.."'")
|
error ("Undefined macro '"..m.."' used in '"..line.."'")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -512,7 +498,7 @@ function compiler.compile_line(line, state)
|
|||||||
if (ast.type == "MacroDef") then
|
if (ast.type == "MacroDef") then
|
||||||
-- Parsed line is a macro definition, so update our dictionary of macros and
|
-- Parsed line is a macro definition, so update our dictionary of macros and
|
||||||
-- return
|
-- return
|
||||||
state.macros[ast.name] = ast.value
|
macro_defs[ast.name] = ast.value
|
||||||
return ast
|
return ast
|
||||||
|
|
||||||
elseif (ast.type == "Rule") then
|
elseif (ast.type == "Rule") then
|
||||||
@@ -522,14 +508,9 @@ function compiler.compile_line(line, state)
|
|||||||
expand_in(ast.filter)
|
expand_in(ast.filter)
|
||||||
|
|
||||||
repeat
|
repeat
|
||||||
expanded = expand_macros(ast, state.macros, false)
|
expanded = expand_macros(ast, macro_defs, false)
|
||||||
until expanded == false
|
until expanded == false
|
||||||
|
|
||||||
if (state.filter_ast == nil) then
|
|
||||||
state.filter_ast = ast.filter.value
|
|
||||||
else
|
|
||||||
state.filter_ast = { type = "BinaryBoolOp", operator = "or", left = state.filter_ast, right = ast.filter.value }
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
error("Unexpected top-level AST type: "..ast.type)
|
error("Unexpected top-level AST type: "..ast.type)
|
||||||
end
|
end
|
||||||
|
@@ -32,7 +32,7 @@ local function install_filter(node)
|
|||||||
--io.write(node.argument.value.." "..node.operator)
|
--io.write(node.argument.value.." "..node.operator)
|
||||||
|
|
||||||
else
|
else
|
||||||
error ("Unexpected type: "..t)
|
error ("Unexpected type in install_filter: "..t)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -49,12 +49,34 @@ end
|
|||||||
|
|
||||||
local state
|
local state
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Sets up compiler state and returns it.
|
||||||
|
|
||||||
|
It holds state such as macro definitions that must be kept across calls
|
||||||
|
to the line-oriented compiler.
|
||||||
|
--]]
|
||||||
|
local function init()
|
||||||
|
return {macros={}, filter_ast=nil}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function load_rule(r)
|
function load_rule(r)
|
||||||
if (state == nil) then
|
if (state == nil) then
|
||||||
state = compiler.init()
|
state = init()
|
||||||
|
end
|
||||||
|
local line_ast = compiler.compile_line(r, state.macros)
|
||||||
|
|
||||||
|
if (line_ast.type == "MacroDef") then
|
||||||
|
return
|
||||||
|
elseif (not (line_ast.type == "Rule")) then
|
||||||
|
error ("Unexpected type in load_rule: "..line_ast.type)
|
||||||
|
end
|
||||||
|
|
||||||
|
if (state.filter_ast == nil) then
|
||||||
|
state.filter_ast = line_ast.filter.value
|
||||||
|
else
|
||||||
|
state.filter_ast = { type = "BinaryBoolOp", operator = "or", left = state.filter_ast, right = line_ast.filter.value }
|
||||||
end
|
end
|
||||||
compiler.compile_line(r, state)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function on_done()
|
function on_done()
|
||||||
|
@@ -5,10 +5,11 @@ if #arg ~= 1 then
|
|||||||
os.exit(1)
|
os.exit(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
local state = compiler.init()
|
local macros = {}
|
||||||
|
local ast
|
||||||
|
|
||||||
local function doit(line)
|
local function doit(line)
|
||||||
local ast = compiler.compile_line(line, state)
|
ast = compiler.compile_line(line, macros)
|
||||||
|
|
||||||
if not ast then
|
if not ast then
|
||||||
print("error", error_msg)
|
print("error", error_msg)
|
||||||
@@ -20,8 +21,8 @@ for str in string.gmatch(arg[1], "([^;]+)") do
|
|||||||
doit(str)
|
doit(str)
|
||||||
end
|
end
|
||||||
|
|
||||||
if not (state.ast == nil) then -- can be nil if only macros
|
if not (ast) then
|
||||||
compiler.parser.print_ast(state.ast)
|
compiler.parser.print_ast(ast)
|
||||||
end
|
end
|
||||||
|
|
||||||
os.exit(0)
|
os.exit(0)
|
||||||
|
Reference in New Issue
Block a user