summaryrefslogtreecommitdiffstats
path: root/lualib/lua_selectors
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rspamd.com>2023-08-07 11:41:28 +0100
committerVsevolod Stakhov <vsevolod@rspamd.com>2023-08-07 11:41:28 +0100
commit662145d0554de5e769b92dab2d41173a98adcee5 (patch)
treeec28311a0bce6181f248ba7b50304293ad764e44 /lualib/lua_selectors
parentbbd88232db43d18f5e0de5a6502848d4074621c5 (diff)
downloadrspamd-662145d0554de5e769b92dab2d41173a98adcee5.tar.gz
rspamd-662145d0554de5e769b92dab2d41173a98adcee5.zip
[Minor] Reformat all Lua code, no functional changes
Diffstat (limited to 'lualib/lua_selectors')
-rw-r--r--lualib/lua_selectors/common.lua5
-rw-r--r--lualib/lua_selectors/extractors.lua140
-rw-r--r--lualib/lua_selectors/init.lua134
-rw-r--r--lualib/lua_selectors/transforms.lua122
4 files changed, 231 insertions, 170 deletions
diff --git a/lualib/lua_selectors/common.lua b/lualib/lua_selectors/common.lua
index c2fe9b58f..7b2372da8 100644
--- a/lualib/lua_selectors/common.lua
+++ b/lualib/lua_selectors/common.lua
@@ -21,8 +21,8 @@ local cr_hash = require 'rspamd_cryptobox_hash'
local blake2b_key = cr_hash.create_specific('blake2'):update('rspamd'):bin()
local function digest_schema()
- return {ts.one_of{'hex', 'base32', 'bleach32', 'rbase32', 'base64'}:is_optional(),
- ts.one_of{'blake2', 'sha256', 'sha1', 'sha512', 'md5'}:is_optional()}
+ return { ts.one_of { 'hex', 'base32', 'bleach32', 'rbase32', 'base64' }:is_optional(),
+ ts.one_of { 'blake2', 'sha256', 'sha1', 'sha512', 'md5' }:is_optional() }
end
exports.digest_schema = digest_schema
@@ -66,7 +66,6 @@ local function create_digest(data, args)
return encode_digest(h, args)
end
-
local function get_cached_or_raw_digest(task, idx, mime_part, args)
if #args == 0 then
-- Optimise as we already have this hash in the API
diff --git a/lualib/lua_selectors/extractors.lua b/lualib/lua_selectors/extractors.lua
index 484adec56..81dfa9d4d 100644
--- a/lualib/lua_selectors/extractors.lua
+++ b/lualib/lua_selectors/extractors.lua
@@ -30,7 +30,9 @@ local function gen_exclude_flags_filter(exclude_flags)
return function(u)
local got_flags = u:get_flags()
for _, flag in ipairs(exclude_flags) do
- if got_flags[flag] then return false end
+ if got_flags[flag] then
+ return false
+ end
end
return true
end
@@ -44,11 +46,11 @@ local extractors = {
return args[1], 'string'
end
- return '','string'
+ return '', 'string'
end,
['description'] = [[Return value from function's argument or an empty string,
For example, `id('Something')` returns a string 'Something']],
- ['args_schema'] = {ts.string:is_optional()}
+ ['args_schema'] = { ts.string:is_optional() }
},
-- Similar but for making lists
['list'] = {
@@ -57,7 +59,7 @@ For example, `id('Something')` returns a string 'Something']],
return fun.map(tostring, args), 'string_list'
end
- return {},'string_list'
+ return {}, 'string_list'
end,
['description'] = [[Return a list from function's arguments or an empty list,
For example, `list('foo', 'bar')` returns a list {'foo', 'bar'}]],
@@ -66,7 +68,9 @@ For example, `list('foo', 'bar')` returns a list {'foo', 'bar'}]],
['ip'] = {
['get_value'] = function(task)
local ip = task:get_ip()
- if ip and ip:is_valid() then return ip,'userdata' end
+ if ip and ip:is_valid() then
+ return ip, 'userdata'
+ end
return nil
end,
['description'] = [[Get source IP address]],
@@ -81,7 +85,7 @@ For example, `list('foo', 'bar')` returns a list {'foo', 'bar'}]],
from = task:get_from(0)
end
if ((from or E)[1] or E).addr then
- return from[1],'table'
+ return from[1], 'table'
end
return nil
end,
@@ -97,7 +101,7 @@ uses any type by default)]],
rcpts = task:get_recipients(0)
end
if ((rcpts or E)[1] or E).addr then
- return rcpts,'table_list'
+ return rcpts, 'table_list'
end
return nil
end,
@@ -111,7 +115,7 @@ uses any type by default)]],
if not country then
return nil
else
- return country,'string'
+ return country, 'string'
end
end,
['description'] = [[Get country (ASN module must be executed first)]],
@@ -124,7 +128,7 @@ uses any type by default)]],
if not asn then
return nil
else
- return asn,'string'
+ return asn, 'string'
end
end,
['description'] = [[Get AS number (ASN module must be executed first)]],
@@ -136,7 +140,7 @@ uses any type by default)]],
if not auser then
return nil
else
- return auser,'string'
+ return auser, 'string'
end
end,
['description'] = 'Get authenticated user name',
@@ -144,14 +148,14 @@ uses any type by default)]],
-- Get principal recipient
['to'] = {
['get_value'] = function(task)
- return task:get_principal_recipient(),'string'
+ return task:get_principal_recipient(), 'string'
end,
['description'] = 'Get principal recipient',
},
-- Get content digest
['digest'] = {
['get_value'] = function(task)
- return task:get_digest(),'string'
+ return task:get_digest(), 'string'
end,
['description'] = 'Get content digest',
},
@@ -160,14 +164,14 @@ uses any type by default)]],
['get_value'] = function(task, args)
local parts = task:get_parts() or E
local digests = {}
- for i,p in ipairs(parts) do
+ for i, p in ipairs(parts) do
if p:is_attachment() then
table.insert(digests, common.get_cached_or_raw_digest(task, i, p, args))
end
end
if #digests > 0 then
- return digests,'string_list'
+ return digests, 'string_list'
end
return nil
@@ -184,7 +188,7 @@ the second optional argument is optional hash type (`blake2`, `sha256`, `sha1`,
local parts = task:get_parts() or E
local files = {}
- for _,p in ipairs(parts) do
+ for _, p in ipairs(parts) do
local fname = p:get_filename()
if fname then
table.insert(files, fname)
@@ -192,7 +196,7 @@ the second optional argument is optional hash type (`blake2`, `sha256`, `sha1`,
end
if #files > 0 then
- return files,'string_list'
+ return files, 'string_list'
end
return nil
@@ -205,7 +209,7 @@ the second optional argument is optional hash type (`blake2`, `sha256`, `sha1`,
local text_parts = task:get_text_parts() or E
local languages = {}
- for _,p in ipairs(text_parts) do
+ for _, p in ipairs(text_parts) do
local lang = p:get_language()
if lang then
table.insert(languages, lang)
@@ -213,7 +217,7 @@ the second optional argument is optional hash type (`blake2`, `sha256`, `sha1`,
end
if #languages > 0 then
- return languages,'string_list'
+ return languages, 'string_list'
end
return nil
@@ -223,7 +227,7 @@ the second optional argument is optional hash type (`blake2`, `sha256`, `sha1`,
-- Get helo value
['helo'] = {
['get_value'] = function(task)
- return task:get_helo(),'string'
+ return task:get_helo(), 'string'
end,
['description'] = 'Get helo value',
},
@@ -238,20 +242,20 @@ the second optional argument is optional hash type (`blake2`, `sha256`, `sha1`,
end
if args[2]:match('full') then
- return task:get_header_full(args[1], strong),'table_list'
+ return task:get_header_full(args[1], strong), 'table_list'
end
- return task:get_header(args[1], strong),'string'
+ return task:get_header(args[1], strong), 'string'
else
- return task:get_header(args[1]),'string'
+ return task:get_header(args[1]), 'string'
end
end,
['description'] = [[Get header with the name that is expected as an argument.
The optional second argument accepts list of flags:
- `full`: returns all headers with this name with all data (like task:get_header_full())
- `strong`: use case sensitive match when matching header's name]],
- ['args_schema'] = {ts.string,
- (ts.pattern("strong") + ts.pattern("full")):is_optional()}
+ ['args_schema'] = { ts.string,
+ (ts.pattern("strong") + ts.pattern("full")):is_optional() }
},
-- Get list of received headers (returns list of tables)
['received'] = {
@@ -261,10 +265,12 @@ The optional second argument accepts list of flags:
return nil
end
if args[1] then
- return fun.map(function(r) return r[args[1]] end, rh), 'string_list'
+ return fun.map(function(r)
+ return r[args[1]]
+ end, rh), 'string_list'
end
- return rh,'table_list'
+ return rh, 'table_list'
end,
['description'] = [[Get list of received headers.
If no arguments specified, returns list of tables. Otherwise, selects a specific element,
@@ -278,9 +284,11 @@ e.g. `by_hostname`]],
return nil
end
if args[1] then
- return fun.map(function(r) return r[args[1]](r) end, urls), 'string_list'
+ return fun.map(function(r)
+ return r[args[1]](r)
+ end, urls), 'string_list'
end
- return urls,'userdata_list'
+ return urls, 'userdata_list'
end,
['description'] = [[Get list of all urls.
If no arguments specified, returns list of url objects. Otherwise, calls a specific method,
@@ -299,21 +307,21 @@ e.g. `get_tld`]],
if not urls[1] then
return nil
end
- return urls,'userdata_list'
+ return urls, 'userdata_list'
end,
['description'] = [[Get most specific urls. Arguments are equal to the Lua API function]],
- ['args_schema'] = {ts.shape{
+ ['args_schema'] = { ts.shape {
limit = ts.number + ts.string / tonumber,
esld_limit = (ts.number + ts.string / tonumber):is_optional(),
exclude_flags = url_flags_ts,
flags = url_flags_ts,
- flags_mode = ts.one_of{'explicit'}:is_optional(),
+ flags_mode = ts.one_of { 'explicit' }:is_optional(),
prefix = ts.string:is_optional(),
need_content = (ts.boolean + ts.string / lua_util.toboolean):is_optional(),
need_emails = (ts.boolean + ts.string / lua_util.toboolean):is_optional(),
need_images = (ts.boolean + ts.string / lua_util.toboolean):is_optional(),
ignore_redirected = (ts.boolean + ts.string / lua_util.toboolean):is_optional(),
- }}
+ } }
},
['specific_urls_filter_map'] = {
['get_value'] = function(task, args)
@@ -331,21 +339,23 @@ e.g. `get_tld`]],
if not urls[1] then
return nil
end
- return fun.filter(function(u) return map:get_key(tostring(u)) end, urls),'userdata_list'
+ return fun.filter(function(u)
+ return map:get_key(tostring(u))
+ end, urls), 'userdata_list'
end,
['description'] = [[Get most specific urls, filtered by some map. Arguments are equal to the Lua API function]],
- ['args_schema'] = {ts.string, ts.shape{
+ ['args_schema'] = { ts.string, ts.shape {
limit = ts.number + ts.string / tonumber,
esld_limit = (ts.number + ts.string / tonumber):is_optional(),
exclude_flags = url_flags_ts,
flags = url_flags_ts,
- flags_mode = ts.one_of{'explicit'}:is_optional(),
+ flags_mode = ts.one_of { 'explicit' }:is_optional(),
prefix = ts.string:is_optional(),
need_content = (ts.boolean + ts.string / lua_util.toboolean):is_optional(),
need_emails = (ts.boolean + ts.string / lua_util.toboolean):is_optional(),
need_images = (ts.boolean + ts.string / lua_util.toboolean):is_optional(),
ignore_redirected = (ts.boolean + ts.string / lua_util.toboolean):is_optional(),
- }}
+ } }
},
-- URLs filtered by flags
['urls_filtered'] = {
@@ -354,13 +364,13 @@ e.g. `get_tld`]],
if not urls[1] then
return nil
end
- return urls,'userdata_list'
+ return urls, 'userdata_list'
end,
['description'] = [[Get list of all urls filtered by flags_include/exclude
(see rspamd_task:get_urls_filtered for description)]],
- ['args_schema'] = {ts.array_of{
+ ['args_schema'] = { ts.array_of {
url_flags_ts:is_optional(), url_flags_ts:is_optional()
- }}
+ } }
},
-- Get all emails
['emails'] = {
@@ -370,9 +380,11 @@ e.g. `get_tld`]],
return nil
end
if args[1] then
- return fun.map(function(r) return r[args[1]](r) end, urls), 'string_list'
+ return fun.map(function(r)
+ return r[args[1]](r)
+ end, urls), 'string_list'
end
- return urls,'userdata_list'
+ return urls, 'userdata_list'
end,
['description'] = [[Get list of all emails.
If no arguments specified, returns list of url objects. Otherwise, calls a specific method,
@@ -383,11 +395,11 @@ e.g. `get_user`]],
['pool_var'] = {
['get_value'] = function(task, args)
local type = args[2] or 'string'
- return task:get_mempool():get_variable(args[1], type),(type)
+ return task:get_mempool():get_variable(args[1], type), (type)
end,
['description'] = [[Get specific pool var. The first argument must be variable name,
the second argument is optional and defines the type (string by default)]],
- ['args_schema'] = {ts.string, ts.string:is_optional()}
+ ['args_schema'] = { ts.string, ts.string:is_optional() }
},
-- Get value of specific key from task cache
['task_cache'] = {
@@ -406,35 +418,35 @@ the second argument is optional and defines the type (string by default)]],
end,
['description'] = [[Get value of specific key from task cache. The first argument must be
the key name]],
- ['args_schema'] = {ts.string}
+ ['args_schema'] = { ts.string }
},
-- Get specific HTTP request header. The first argument must be header name.
['request_header'] = {
['get_value'] = function(task, args)
local hdr = task:get_request_header(args[1])
if hdr then
- return hdr,'string'
+ return hdr, 'string'
end
return nil
end,
['description'] = [[Get specific HTTP request header.
The first argument must be header name.]],
- ['args_schema'] = {ts.string}
+ ['args_schema'] = { ts.string }
},
-- Get task date, optionally formatted
['time'] = {
['get_value'] = function(task, args)
local what = args[1] or 'message'
- local dt = task:get_date{format = what, gmt = true}
+ local dt = task:get_date { format = what, gmt = true }
if dt then
if args[2] then
-- Should be in format !xxx, as dt is in GMT
- return os.date(args[2], dt),'string'
+ return os.date(args[2], dt), 'string'
end
- return tostring(dt),'string'
+ return tostring(dt), 'string'
end
return nil
@@ -444,8 +456,8 @@ The first argument must be header name.]],
- `message`: timestamp as defined by `Date` header
The second argument is optional time format, see [os.date](http://pgl.yoyo.org/luai/i/os.date) description]],
- ['args_schema'] = {ts.one_of{'connect', 'message'}:is_optional(),
- ts.string:is_optional()}
+ ['args_schema'] = { ts.one_of { 'connect', 'message' }:is_optional(),
+ ts.string:is_optional() }
},
-- Get text words from a message
['words'] = {
@@ -473,13 +485,15 @@ The first argument must be header name.]],
- `norm`: normalised words (lowercased)
- `full`: list of tables
]],
- ['args_schema'] = { ts.one_of { 'stem', 'raw', 'norm', 'full' }:is_optional()},
+ ['args_schema'] = { ts.one_of { 'stem', 'raw', 'norm', 'full' }:is_optional() },
},
-- Get queue ID
['queueid'] = {
['get_value'] = function(task)
local queueid = task:get_queue_id()
- if queueid then return queueid,'string' end
+ if queueid then
+ return queueid, 'string'
+ end
return nil
end,
['description'] = [[Get queue ID]],
@@ -488,7 +502,9 @@ The first argument must be header name.]],
['uid'] = {
['get_value'] = function(task)
local uid = task:get_uid()
- if uid then return uid,'string' end
+ if uid then
+ return uid, 'string'
+ end
return nil
end,
['description'] = [[Get ID of the task being processed]],
@@ -497,7 +513,9 @@ The first argument must be header name.]],
['messageid'] = {
['get_value'] = function(task)
local mid = task:get_message_id()
- if mid then return mid,'string' end
+ if mid then
+ return mid, 'string'
+ end
return nil
end,
['description'] = [[Get message ID]],
@@ -507,25 +525,25 @@ The first argument must be header name.]],
['get_value'] = function(task, args)
local symbol = task:get_symbol(args[1], args[2])
if symbol then
- return symbol[1],'table'
+ return symbol[1], 'table'
end
end,
['description'] = 'Get specific symbol. The first argument must be the symbol name. ' ..
- 'The second argument is an optional shadow result name. ' ..
- 'Returns the symbol table. See task:get_symbol()',
- ['args_schema'] = {ts.string, ts.string:is_optional()}
+ 'The second argument is an optional shadow result name. ' ..
+ 'Returns the symbol table. See task:get_symbol()',
+ ['args_schema'] = { ts.string, ts.string:is_optional() }
},
-- Get full scan result
['scan_result'] = {
['get_value'] = function(task, args)
local res = task:get_metric_result(args[1])
if res then
- return res,'table'
+ return res, 'table'
end
end,
['description'] = 'Get full scan result (either default or shadow if shadow result name is specified)' ..
'Returns the result table. See task:get_metric_result()',
- ['args_schema'] = {ts.string:is_optional()}
+ ['args_schema'] = { ts.string:is_optional() }
},
-- Get list of metatokens as strings
['metatokens'] = {
diff --git a/lualib/lua_selectors/init.lua b/lualib/lua_selectors/init.lua
index 5823fef96..6cdd11584 100644
--- a/lualib/lua_selectors/init.lua
+++ b/lualib/lua_selectors/init.lua
@@ -51,21 +51,21 @@ local function implicit_tostring(t, ud_or_table)
if t == 'table' then
-- Table (very special)
if ud_or_table.value then
- return ud_or_table.value,'string'
+ return ud_or_table.value, 'string'
elseif ud_or_table.addr then
- return ud_or_table.addr,'string'
+ return ud_or_table.addr, 'string'
end
- return logger.slog("%s", ud_or_table),'string'
+ return logger.slog("%s", ud_or_table), 'string'
elseif (t == 'string' or t == 'text') and type(ud_or_table) == 'userdata' then
if ud_or_table.cookie and ud_or_table.cookie == text_cookie then
-- Preserve opaque
- return ud_or_table,'string'
+ return ud_or_table, 'string'
else
- return tostring(ud_or_table),'string'
+ return tostring(ud_or_table), 'string'
end
elseif t ~= 'nil' then
- return tostring(ud_or_table),'string'
+ return tostring(ud_or_table), 'string'
end
return nil
@@ -84,7 +84,7 @@ local function process_selector(task, sel)
return pure_type(t)
end
- local input,etype = sel.selector.get_value(task, sel.selector.args)
+ local input, etype = sel.selector.get_value(task, sel.selector.args)
if not input then
lua_util.debugm(M, task, 'no value extracted for %s', sel.selector.name)
@@ -98,14 +98,16 @@ local function process_selector(task, sel)
local first_elt = pipe[1]
if first_elt and (first_elt.method or
- fun.any(function(t) return t == 'userdata' or t == 'table' end, first_elt.types)) then
+ fun.any(function(t)
+ return t == 'userdata' or t == 'table'
+ end, first_elt.types)) then
-- Explicit conversion
local meth = first_elt
if meth.types[etype] then
lua_util.debugm(M, task, 'apply method `%s` to %s',
meth.name, etype)
- input,etype = meth.process(input, etype, meth.args)
+ input, etype = meth.process(input, etype, meth.args)
else
local pt = pure_type(etype)
@@ -114,7 +116,9 @@ local function process_selector(task, sel)
meth.name, pt)
-- Map method to a list of inputs, excluding empty elements
-- We need to fold it down here to get a proper type resolution
- input = fun.totable(fun.filter(function(map_elt, _) return map_elt end,
+ input = fun.totable(fun.filter(function(map_elt, _)
+ return map_elt
+ end,
fun.map(function(list_elt)
local ret, ty = meth.process(list_elt, pt, meth.args)
etype = ty
@@ -139,7 +143,9 @@ local function process_selector(task, sel)
etype = 'string'
else
lua_util.debugm(M, task, 'apply implicit map %s->string', pt)
- input = fun.filter(function(map_elt) return map_elt end,
+ input = fun.filter(function(map_elt)
+ return map_elt
+ end,
fun.map(function(list_elt)
local ret = implicit_tostring(pt, list_elt)
return ret
@@ -166,16 +172,20 @@ local function process_selector(task, sel)
if pt and x.types['list'] then
-- Generic list processor
lua_util.debugm(M, task, 'apply list function `%s` to %s', x.name, t)
- return {x.process(value, t, x.args)}
+ return { x.process(value, t, x.args) }
elseif pt and x.map_type and x.types[pt] then
local map_type = x.map_type .. '_list'
lua_util.debugm(M, task, 'map `%s` to list of %s resulting %s',
x.name, pt, map_type)
-- Apply map, filtering empty values
return {
- fun.filter(function(map_elt) return map_elt end,
+ fun.filter(function(map_elt)
+ return map_elt
+ end,
fun.map(function(list_elt)
- if not list_elt then return nil end
+ if not list_elt then
+ return nil
+ end
local ret, _ = x.process(list_elt, pt, x.args)
return ret
end, value)),
@@ -187,14 +197,16 @@ local function process_selector(task, sel)
end
lua_util.debugm(M, task, 'apply %s to %s', x.name, t)
- return {x.process(value, t, x.args)}
+ return { x.process(value, t, x.args) }
end
local res = fun.foldl(fold_function,
- {input, etype},
+ { input, etype },
pipe)
- if not res or not res[1] then return nil end -- Pipeline failed
+ if not res or not res[1] then
+ return nil
+ end -- Pipeline failed
if not allowed_type(res[2]) then
-- Search for implicit conversion
@@ -202,7 +214,9 @@ local function process_selector(task, sel)
if pt then
lua_util.debugm(M, task, 'apply implicit map %s->string_list', pt)
- res[1] = fun.map(function(e) return implicit_tostring(pt, e) end, res[1])
+ res[1] = fun.map(function(e)
+ return implicit_tostring(pt, e)
+ end, res[1])
res[2] = 'string_list'
else
res[1] = implicit_tostring(res[2], res[1])
@@ -222,14 +236,14 @@ end
local function make_grammar()
local l = require "lpeg"
- local spc = l.S(" \t\n")^0
+ local spc = l.S(" \t\n") ^ 0
local cont = l.R("\128\191") -- continuation byte
local utf8_high = l.R("\194\223") * cont
+ l.R("\224\239") * cont * cont
+ l.R("\240\244") * cont * cont * cont
- local atom = l.C((l.R("az") + l.R("AZ") + l.R("09") + l.S("_-") + utf8_high)^1)
- local singlequoted_string = l.P "'" * l.C(((1 - l.S "'\r\n\f\\") + (l.P'\\' * 1))^0) * "'"
- local doublequoted_string = l.P '"' * l.C(((1 - l.S'"\r\n\f\\') + (l.P'\\' * 1))^0) * '"'
+ local atom = l.C((l.R("az") + l.R("AZ") + l.R("09") + l.S("_-") + utf8_high) ^ 1)
+ local singlequoted_string = l.P "'" * l.C(((1 - l.S "'\r\n\f\\") + (l.P '\\' * 1)) ^ 0) * "'"
+ local doublequoted_string = l.P '"' * l.C(((1 - l.S '"\r\n\f\\') + (l.P '\\' * 1)) ^ 0) * '"'
local argument = atom + singlequoted_string + doublequoted_string
local dot = l.P(".")
local semicolon = l.P(":")
@@ -239,20 +253,22 @@ local function make_grammar()
local tbl_ebrace = spc * "}"
local ebrace = spc * ")"
local comma = spc * "," * spc
- local sel_separator = spc * l.S";*" * spc
+ local sel_separator = spc * l.S ";*" * spc
- return l.P{
+ return l.P {
"LIST";
- LIST = l.Ct(l.V("EXPR")) * (sel_separator * l.Ct(l.V("EXPR")))^0,
- EXPR = l.V("FUNCTION") * (semicolon * l.V("METHOD"))^-1 * (dot * l.V("PROCESSOR"))^0,
- PROCESSOR = l.Ct(atom * spc * (obrace * l.V("ARG_LIST") * ebrace)^0),
- FUNCTION = l.Ct(atom * spc * (obrace * l.V("ARG_LIST") * ebrace)^0),
- METHOD = l.Ct(atom / function(e) return '__' .. e end * spc * (obrace * l.V("ARG_LIST") * ebrace)^0),
- ARG_LIST = l.Ct((l.V("ARG") * comma^0)^0),
+ LIST = l.Ct(l.V("EXPR")) * (sel_separator * l.Ct(l.V("EXPR"))) ^ 0,
+ EXPR = l.V("FUNCTION") * (semicolon * l.V("METHOD")) ^ -1 * (dot * l.V("PROCESSOR")) ^ 0,
+ PROCESSOR = l.Ct(atom * spc * (obrace * l.V("ARG_LIST") * ebrace) ^ 0),
+ FUNCTION = l.Ct(atom * spc * (obrace * l.V("ARG_LIST") * ebrace) ^ 0),
+ METHOD = l.Ct(atom / function(e)
+ return '__' .. e
+ end * spc * (obrace * l.V("ARG_LIST") * ebrace) ^ 0),
+ ARG_LIST = l.Ct((l.V("ARG") * comma ^ 0) ^ 0),
ARG = l.Cf(tbl_obrace * l.V("NAMED_ARG") * tbl_ebrace, rawset) + argument + l.V("LIST_ARGS"),
- NAMED_ARG = (l.Ct("") * l.Cg(argument * eqsign * (argument + l.V("LIST_ARGS")) * comma^0)^0),
+ NAMED_ARG = (l.Ct("") * l.Cg(argument * eqsign * (argument + l.V("LIST_ARGS")) * comma ^ 0) ^ 0),
LIST_ARGS = l.Ct(tbl_obrace * l.V("LIST_ARG") * tbl_ebrace),
- LIST_ARG = l.Cg(argument * comma^0)^0,
+ LIST_ARG = l.Cg(argument * comma ^ 0) ^ 0,
}
end
@@ -262,27 +278,29 @@ local parser = make_grammar()
-- @function lua_selectors.parse_selector(cfg, str)
--]]
exports.parse_selector = function(cfg, str)
- local parsed = {parser:match(str)}
+ local parsed = { parser:match(str) }
local output = {}
- if not parsed or not parsed[1] then return nil end
+ if not parsed or not parsed[1] then
+ return nil
+ end
local function check_args(name, schema, args)
if schema then
if getmetatable(schema) then
-- Schema covers all arguments
- local res,err = schema:transform(args)
+ local res, err = schema:transform(args)
if not res then
logger.errx(rspamd_config, 'invalid arguments for %s: %s', name, err)
return false
else
- for i,elt in ipairs(res) do
+ for i, elt in ipairs(res) do
args[i] = elt
end
end
else
- for i,selt in ipairs(schema) do
- local res,err = selt:transform(args[i])
+ for i, selt in ipairs(schema) do
+ local res, err = selt:transform(args[i])
if err then
logger.errx(rspamd_config, 'invalid arguments for %s: argument number: %s, error: %s', name, i, err)
@@ -301,7 +319,7 @@ exports.parse_selector = function(cfg, str)
-- table of individual selectors
-- each selector: list of functions
-- each function: function name + optional list of arguments
- for _,sel in ipairs(parsed) do
+ for _, sel in ipairs(parsed) do
local res = {
selector = {},
processor_pipe = {},
@@ -364,13 +382,15 @@ exports.parse_selector = function(cfg, str)
local ret_type = type(ret)
- if ret_type == 'nil' then return nil end
+ if ret_type == 'nil' then
+ return nil
+ end
-- Now apply types heuristic
if ret_type == 'string' then
- return ret,'string'
+ return ret, 'string'
elseif ret_type == 'table' then
-- TODO: we need to ensure that 1) table is numeric 2) table has merely strings
- return ret,'string_list'
+ return ret, 'string_list'
else
return implicit_tostring(ret_type, ret)
end
@@ -452,11 +472,13 @@ end
exports.process_selectors = function(task, selectors_pipe)
local ret = {}
- for _,sel in ipairs(selectors_pipe) do
+ for _, sel in ipairs(selectors_pipe) do
local r = process_selector(task, sel)
-- If any element is nil, then the whole selector is nil
- if not r then return nil end
+ if not r then
+ return nil
+ end
table.insert(ret, r)
end
@@ -467,13 +489,17 @@ end
-- @function lua_selectors.combine_selectors(task, selectors, delimiter)
--]]
exports.combine_selectors = function(_, selectors, delimiter)
- if not delimiter then delimiter = '' end
+ if not delimiter then
+ delimiter = ''
+ end
- if not selectors then return nil end
+ if not selectors then
+ return nil
+ end
local have_tables, have_userdata
- for _,s in ipairs(selectors) do
+ for _, s in ipairs(selectors) do
if type(s) == 'table' then
have_tables = true
elseif type(s) == 'userdata' then
@@ -493,7 +519,7 @@ exports.combine_selectors = function(_, selectors, delimiter)
local tbl = {}
local res = {}
- for i,s in ipairs(selectors) do
+ for i, s in ipairs(selectors) do
if type(s) == 'string' then
rawset(tbl, i, fun.duplicate(s))
elseif type(s) == 'userdata' then
@@ -505,7 +531,7 @@ exports.combine_selectors = function(_, selectors, delimiter)
end
fun.each(function(...)
- table.insert(res, table.concat({...}, delimiter))
+ table.insert(res, table.concat({ ... }, delimiter))
end, fun.zip(lua_util.unpack(tbl)))
return res
@@ -520,7 +546,7 @@ exports.flatten_selectors = function(_, selectors, _)
local res = {}
local function fill(tbl)
- for _,s in ipairs(tbl) do
+ for _, s in ipairs(tbl) do
if type(s) == 'string' then
rawset(res, #res + 1, s)
elseif type(s) == 'userdata' then
@@ -553,7 +579,7 @@ exports.kv_table_from_pairs = function(log_obj, selectors, _)
tbl_len)
return
end
- for i=1,tbl_len,2 do
+ for i = 1, tbl_len, 2 do
local k = tostring(tbl[i])
local v = tbl[i + 1]
if type(v) == 'string' then
@@ -561,7 +587,9 @@ exports.kv_table_from_pairs = function(log_obj, selectors, _)
elseif type(v) == 'userdata' then
res[k] = tostring(v)
else
- res[k] = fun.totable(fun.map(function(elt) return tostring(elt) end, v))
+ res[k] = fun.totable(fun.map(function(elt)
+ return tostring(elt)
+ end, v))
end
end
end
@@ -605,7 +633,7 @@ exports.create_selector_closure = function(cfg, selector_str, delimiter, flatten
end
local function display_selectors(tbl)
- return fun.tomap(fun.map(function(k,v)
+ return fun.tomap(fun.map(function(k, v)
return k, fun.tomap(fun.filter(function(kk, vv)
return type(vv) ~= 'function'
end, v))
diff --git a/lualib/lua_selectors/transforms.lua b/lualib/lua_selectors/transforms.lua
index 55e1bffb7..4b839de28 100644
--- a/lualib/lua_selectors/transforms.lua
+++ b/lualib/lua_selectors/transforms.lua
@@ -36,7 +36,7 @@ local transform_function = {
},
['map_type'] = 'string',
['process'] = function(inp, _)
- return inp:lower(),'string'
+ return inp:lower(), 'string'
end,
['description'] = 'Returns the lowercased string',
},
@@ -57,7 +57,7 @@ local transform_function = {
['list'] = true,
},
['process'] = function(inp, t)
- return fun.head(inp),pure_type(t)
+ return fun.head(inp), pure_type(t)
end,
['description'] = 'Returns the first element',
},
@@ -67,7 +67,7 @@ local transform_function = {
['list'] = true,
},
['process'] = function(inp, t)
- return fun.nth(fun.length(inp), inp),pure_type(t)
+ return fun.nth(fun.length(inp), inp), pure_type(t)
end,
['description'] = 'Returns the last element',
},
@@ -77,30 +77,30 @@ local transform_function = {
['list'] = true,
},
['process'] = function(inp, t, args)
- return fun.nth(args[1] or 1, inp),pure_type(t)
+ return fun.nth(args[1] or 1, inp), pure_type(t)
end,
['description'] = 'Returns the nth element',
- ['args_schema'] = {ts.number + ts.string / tonumber}
+ ['args_schema'] = { ts.number + ts.string / tonumber }
},
['take_n'] = {
['types'] = {
['list'] = true,
},
['process'] = function(inp, t, args)
- return fun.take_n(args[1] or 1, inp),t
+ return fun.take_n(args[1] or 1, inp), t
end,
['description'] = 'Returns the n first elements',
- ['args_schema'] = {ts.number + ts.string / tonumber}
+ ['args_schema'] = { ts.number + ts.string / tonumber }
},
['drop_n'] = {
['types'] = {
['list'] = true,
},
['process'] = function(inp, t, args)
- return fun.drop_n(args[1] or 1, inp),t
+ return fun.drop_n(args[1] or 1, inp), t
end,
['description'] = 'Returns list without the first n elements',
- ['args_schema'] = {ts.number + ts.string / tonumber}
+ ['args_schema'] = { ts.number + ts.string / tonumber }
},
-- Joins strings into a single string using separator in the argument
['join'] = {
@@ -111,7 +111,7 @@ local transform_function = {
return table.concat(fun.totable(inp), args[1] or ''), 'string'
end,
['description'] = 'Joins strings into a single string using separator in the argument',
- ['args_schema'] = {ts.string:is_optional()}
+ ['args_schema'] = { ts.string:is_optional() }
},
-- Joins strings into a set of strings using N elements and a separator in the argument
['join_nth'] = {
@@ -124,13 +124,13 @@ local transform_function = {
local inp_t = fun.totable(inp)
local res = {}
- for i=1, #inp_t, step do
+ for i = 1, #inp_t, step do
table.insert(res, table.concat(inp_t, sep, i, i + step))
end
- return res,'string_list'
+ return res, 'string_list'
end,
['description'] = 'Joins strings into a set of strings using N elements and a separator in the argument',
- ['args_schema'] = {ts.number + ts.string / tonumber, ts.string:is_optional()}
+ ['args_schema'] = { ts.number + ts.string / tonumber, ts.string:is_optional() }
},
-- Joins tables into a table of strings
['join_tables'] = {
@@ -139,10 +139,12 @@ local transform_function = {
},
['process'] = function(inp, _, args)
local sep = args[1] or ''
- return fun.map(function(t) return table.concat(t, sep) end, inp), 'string_list'
+ return fun.map(function(t)
+ return table.concat(t, sep)
+ end, inp), 'string_list'
end,
['description'] = 'Joins tables into a table of strings',
- ['args_schema'] = {ts.string:is_optional()}
+ ['args_schema'] = { ts.string:is_optional() }
},
-- Sort strings
['sort'] = {
@@ -166,7 +168,9 @@ local transform_function = {
tmp[val] = true
end, inp)
- return fun.map(function(k, _) return k end, tmp), t
+ return fun.map(function(k, _)
+ return k
+ end, tmp), t
end,
['description'] = 'Returns a list of unique elements (using a hash table)',
},
@@ -177,7 +181,7 @@ local transform_function = {
},
['map_type'] = 'string',
['process'] = function(inp, _, args)
- return common.create_digest(inp, args),'string'
+ return common.create_digest(inp, args), 'string'
end,
['description'] = [[Create a digest from a string.
The first argument is encoding (`hex`, `base32` (and forms `bleach32`, `rbase32`), `base64`),
@@ -197,8 +201,8 @@ the second argument is optional hash type (`blake2`, `sha256`, `sha1`, `sha512`,
return inp:sub(start_pos, end_pos), 'string'
end,
['description'] = 'Extracts substring; the first argument is start, the second is the last (like in Lua)',
- ['args_schema'] = {(ts.number + ts.string / tonumber):is_optional(),
- (ts.number + ts.string / tonumber):is_optional()}
+ ['args_schema'] = { (ts.number + ts.string / tonumber):is_optional(),
+ (ts.number + ts.string / tonumber):is_optional() }
},
-- Prepends a string or a strings list
['prepend'] = {
@@ -257,13 +261,13 @@ the second argument is optional hash type (`blake2`, `sha256`, `sha1`, `sha512`,
end
end
flatten_table(res)
- return flattened_table,'string_list'
+ return flattened_table, 'string_list'
end
return nil
end,
['description'] = 'Regexp matching, returns all matches flattened in a single list',
- ['args_schema'] = {ts.string}
+ ['args_schema'] = { ts.string }
},
-- Returns a value if it exists in some map (or acts like a `filter` function)
['filter_map'] = {
@@ -282,13 +286,13 @@ the second argument is optional hash type (`blake2`, `sha256`, `sha1`, `sha512`,
local res = map:get_key(inp)
if res then
- return inp,t
+ return inp, t
end
return nil
end,
['description'] = 'Returns a value if it exists in some map (or acts like a `filter` function)',
- ['args_schema'] = {ts.string}
+ ['args_schema'] = { ts.string }
},
-- Returns a value if it exists in some map (or acts like a `filter` function)
['except_map'] = {
@@ -307,13 +311,13 @@ the second argument is optional hash type (`blake2`, `sha256`, `sha1`, `sha512`,
local res = map:get_key(inp)
if not res then
- return inp,t
+ return inp, t
end
return nil
end,
['description'] = 'Returns a value if it does not exists in some map (or acts like a `except` function)',
- ['args_schema'] = {ts.string}
+ ['args_schema'] = { ts.string }
},
-- Returns a value from some map corresponding to some key (or acts like a `map` function)
['apply_map'] = {
@@ -332,13 +336,13 @@ the second argument is optional hash type (`blake2`, `sha256`, `sha1`, `sha512`,
local res = map:get_key(inp)
if res then
- return res,t
+ return res, t
end
return nil
end,
['description'] = 'Returns a value from some map corresponding to some key (or acts like a `map` function)',
- ['args_schema'] = {ts.string}
+ ['args_schema'] = { ts.string }
},
-- Drops input value and return values from function's arguments or an empty string
['id'] = {
@@ -349,12 +353,12 @@ the second argument is optional hash type (`blake2`, `sha256`, `sha1`, `sha512`,
['map_type'] = 'string',
['process'] = function(_, _, args)
if args[1] and args[2] then
- return fun.map(tostring, args),'string_list'
+ return fun.map(tostring, args), 'string_list'
elseif args[1] then
- return args[1],'string'
+ return args[1], 'string'
end
- return '','string'
+ return '', 'string'
end,
['description'] = 'Drops input value and return values from function\'s arguments or an empty string',
['args_schema'] = (ts.string + ts.array_of(ts.string)):is_optional()
@@ -366,14 +370,14 @@ the second argument is optional hash type (`blake2`, `sha256`, `sha1`, `sha512`,
['map_type'] = 'string',
['process'] = function(inp, _, args)
if inp == args[1] then
- return inp,'string'
+ return inp, 'string'
end
return nil
end,
['description'] = [[Boolean function equal.
Returns either nil or its argument if input is equal to argument]],
- ['args_schema'] = {ts.string}
+ ['args_schema'] = { ts.string }
},
-- Boolean function in, returns either nil or its input if input is in args list
['in'] = {
@@ -382,7 +386,11 @@ Returns either nil or its argument if input is equal to argument]],
},
['map_type'] = 'string',
['process'] = function(inp, t, args)
- for _,a in ipairs(args) do if a == inp then return inp,t end end
+ for _, a in ipairs(args) do
+ if a == inp then
+ return inp, t
+ end
+ end
return nil
end,
['description'] = [[Boolean function in.
@@ -395,8 +403,12 @@ Returns either nil or its input if input is in args list]],
},
['map_type'] = 'string',
['process'] = function(inp, t, args)
- for _,a in ipairs(args) do if a == inp then return nil end end
- return inp,t
+ for _, a in ipairs(args) do
+ if a == inp then
+ return nil
+ end
+ end
+ return inp, t
end,
['description'] = [[Boolean function not in.
Returns either nil or its input if input is not in args list]],
@@ -411,12 +423,12 @@ Returns either nil or its input if input is not in args list]],
if inp then
return nil
else
- return (args[1] or 'true'),'string'
+ return (args[1] or 'true'), 'string'
end
end,
['description'] = [[Inverses input.
Empty string comes the first argument or 'true', non-empty string comes nil]],
- ['args_schema'] = {ts.string:is_optional()}
+ ['args_schema'] = { ts.string:is_optional() }
},
['ipmask'] = {
['types'] = {
@@ -436,19 +448,19 @@ Empty string comes the first argument or 'true', non-empty string comes nil]],
if ip:get_version() == 4 then
local mask = tonumber(args[1])
- return ip:apply_mask(mask):to_string(),'string'
+ return ip:apply_mask(mask):to_string(), 'string'
else
-- IPv6 takes the second argument or the first one...
local mask_str = args[2] or args[1]
local mask = tonumber(mask_str)
- return ip:apply_mask(mask):to_string(),'string'
+ return ip:apply_mask(mask):to_string(), 'string'
end
end,
['description'] = 'Applies mask to IP address.' ..
- ' The first argument is the mask for IPv4 addresses, the second is the mask for IPv6 addresses.',
- ['args_schema'] = {(ts.number + ts.string / tonumber),
- (ts.number + ts.string / tonumber):is_optional()}
+ ' The first argument is the mask for IPv4 addresses, the second is the mask for IPv6 addresses.',
+ ['args_schema'] = { (ts.number + ts.string / tonumber),
+ (ts.number + ts.string / tonumber):is_optional() }
},
-- Returns the string(s) with all non ascii chars replaced
['to_ascii'] = {
@@ -460,16 +472,16 @@ Empty string comes the first argument or 'true', non-empty string comes nil]],
['process'] = function(inp, _, args)
if type(inp) == 'table' then
return fun.map(
- function(s)
- return string.gsub(tostring(s), '[\128-\255]', args[1] or '?')
- end, inp), 'string_list'
+ function(s)
+ return string.gsub(tostring(s), '[\128-\255]', args[1] or '?')
+ end, inp), 'string_list'
else
return string.gsub(tostring(inp), '[\128-\255]', '?'), 'string'
end
end,
['description'] = 'Returns the string with all non-ascii bytes replaced with the character ' ..
- 'given as second argument or `?`',
- ['args_schema'] = {ts.string:is_optional()}
+ 'given as second argument or `?`',
+ ['args_schema'] = { ts.string:is_optional() }
},
-- Extracts tld from a hostname
['get_tld'] = {
@@ -478,7 +490,7 @@ Empty string comes the first argument or 'true', non-empty string comes nil]],
},
['map_type'] = 'string',
['process'] = function(inp, _, _)
- return rspamd_util.get_tld(inp),'string'
+ return rspamd_util.get_tld(inp), 'string'
end,
['description'] = 'Extracts tld from a hostname represented as a string',
['args_schema'] = {}
@@ -498,7 +510,7 @@ Empty string comes the first argument or 'true', non-empty string comes nil]],
return rspamd_util.pack(string.rep(fmt, #res), lua_util.unpack(res)), 'string'
end,
['description'] = 'Converts a list of strings to numbers & returns a packed string',
- ['args_schema'] = {ts.string:is_optional()}
+ ['args_schema'] = { ts.string:is_optional() }
},
-- Filter nils from a list
['filter_string_nils'] = {
@@ -506,7 +518,9 @@ Empty string comes the first argument or 'true', non-empty string comes nil]],
['string_list'] = true
},
['process'] = function(inp, _, _)
- return fun.filter(function(val) return type(val) == 'string' and val ~= 'nil' end, inp), 'string_list'
+ return fun.filter(function(val)
+ return type(val) == 'string' and val ~= 'nil'
+ end, inp), 'string_list'
end,
['description'] = 'Removes all nils from a list of strings (when converted implicitly)',
['args_schema'] = {}
@@ -518,12 +532,14 @@ Empty string comes the first argument or 'true', non-empty string comes nil]],
},
['process'] = function(inp, _, args)
local res = {}
- for _,arg in ipairs(args) do
+ for _, arg in ipairs(args) do
local meth = inp[arg]
local ret = meth(inp)
- if ret then table.insert(res, tostring(ret)) end
+ if ret then
+ table.insert(res, tostring(ret))
+ end
end
- return res,'string_list'
+ return res, 'string_list'
end,
['description'] = 'Apply a list of method calls to the userdata object',
}