aboutsummaryrefslogtreecommitdiffstats
path: root/lualib/lua_selectors
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2020-05-14 12:15:41 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2020-05-14 12:16:19 +0100
commitfe590fd7b5ea560fd468d57296c4bcf25e6cf320 (patch)
treea4f491ff149baf7d1636af4357ce8463901eb2c7 /lualib/lua_selectors
parentb9a659c5d01a92d124344d62dff70da431c6443c (diff)
downloadrspamd-fe590fd7b5ea560fd468d57296c4bcf25e6cf320.tar.gz
rspamd-fe590fd7b5ea560fd468d57296c4bcf25e6cf320.zip
[Fix] Fix calling of methods in selectors
Diffstat (limited to 'lualib/lua_selectors')
-rw-r--r--lualib/lua_selectors/init.lua133
-rw-r--r--lualib/lua_selectors/transforms.lua3
2 files changed, 71 insertions, 65 deletions
diff --git a/lualib/lua_selectors/init.lua b/lualib/lua_selectors/init.lua
index 11fcd55d1..ba20810c5 100644
--- a/lualib/lua_selectors/init.lua
+++ b/lualib/lua_selectors/init.lua
@@ -35,6 +35,7 @@ local fun = require 'fun'
local lua_util = require "lua_util"
local M = "selectors"
local rspamd_text = require "rspamd_text"
+local unpack_function = table.unpack or unpack
local E = {}
local extractors = require "lua_selectors/extractors"
@@ -46,6 +47,28 @@ local function pure_type(ltype)
return ltype:match('^(.*)_list$')
end
+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'
+ elseif ud_or_table.addr then
+ return ud_or_table.addr,'string'
+ end
+
+ return logger.slog("%s", ud_or_table),'string'
+ elseif t == 'userdata' then
+ if t.cookie and t.cookie == text_cookie then
+ -- Preserve opaque
+ return ud_or_table,'string'
+ else
+ return tostring(ud_or_table),'string'
+ end
+ else
+ return tostring(ud_or_table),'string'
+ end
+end
+
local function process_selector(task, sel)
local function allowed_type(t)
if t == 'string' or t == 'text' or t == 'string_list' or t == 'text_list' then
@@ -59,28 +82,6 @@ local function process_selector(task, sel)
return pure_type(t)
end
- 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'
- elseif ud_or_table.addr then
- return ud_or_table.addr,'string'
- end
-
- return logger.slog("%s", ud_or_table),'string'
- elseif t == 'userdata' then
- if t.cookie and t.cookie == text_cookie then
- -- Preserve opaque
- return ud_or_table,'string'
- else
- return tostring(ud_or_table),'string'
- end
- else
- return tostring(ud_or_table),'string'
- end
- end
-
local input,etype = sel.selector.get_value(task, sel.selector.args)
if not input then
@@ -92,55 +93,51 @@ local function process_selector(task, sel)
sel.selector.name, etype)
local pipe = sel.processor_pipe or E
+ local first_elt = pipe[1]
- if etype:match('^userdata') or etype:match('^table') then
- -- Apply userdata conversion first
- local first_elt = pipe[1]
-
- if first_elt and first_elt.method 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)
- else
- local pt = pure_type(etype)
+ if first_elt and first_elt.method then
+ -- Explicit conversion
+ local meth = first_elt
- if meth.types[pt] then
- lua_util.debugm(M, task, 'map method `%s` to list of %s',
- meth.name, pt)
- -- Map method to a list of inputs, excluding empty elements
- input = fun.filter(function(map_elt) return map_elt end,
- fun.map(function(list_elt)
- local ret, _ = meth.process(list_elt, pt)
- return ret
- end, input))
- etype = 'string_list'
- end
- end
- -- Remove method from the pipeline
- pipe = fun.drop_n(1, pipe)
+ if meth.types[etype] then
+ lua_util.debugm(M, task, 'apply method `%s` to %s',
+ meth.name, etype)
+ input,etype = meth.process(input, etype)
else
- -- Implicit conversion
-
local pt = pure_type(etype)
- if not pt then
- lua_util.debugm(M, task, 'apply implicit conversion %s->string', etype)
- input = implicit_tostring(etype, input)
- etype = 'string'
- else
- lua_util.debugm(M, task, 'apply implicit map %s->string', pt)
+ if meth.types[pt] then
+ lua_util.debugm(M, task, 'map method `%s` to list of %s',
+ meth.name, pt)
+ -- Map method to a list of inputs, excluding empty elements
input = fun.filter(function(map_elt) return map_elt end,
fun.map(function(list_elt)
- local ret = implicit_tostring(pt, list_elt)
+ local ret, _ = meth.process(list_elt, pt)
return ret
end, input))
etype = 'string_list'
end
end
+ -- Remove method from the pipeline
+ pipe = fun.drop_n(1, pipe)
+ elseif etype:match('^userdata') or etype:match('^table') then
+ -- Implicit conversion
+
+ local pt = pure_type(etype)
+
+ if not pt then
+ lua_util.debugm(M, task, 'apply implicit conversion %s->string', etype)
+ input = implicit_tostring(etype, input)
+ etype = 'string'
+ else
+ lua_util.debugm(M, task, 'apply implicit map %s->string', pt)
+ input = fun.filter(function(map_elt) return map_elt end,
+ fun.map(function(list_elt)
+ local ret = implicit_tostring(pt, list_elt)
+ return ret
+ end, input))
+ etype = 'string_list'
+ end
end
-- Now we fold elements using left fold
@@ -337,14 +334,24 @@ exports.parse_selector = function(cfg, str)
types = {
userdata = true,
table = true,
+ string = true,
},
map_type = 'string',
process = function(inp, t, args)
- if t == 'userdata' then
- return inp[method_name](inp, args),'string'
- else
- -- Table
+ if t == 'table' then
return inp[method_name],'string'
+ else
+ -- We call method unpacking arguments and dropping all but the first result returned
+ local ret = (inp[method_name](inp, unpack_function(args)))
+ local ret_type = type(ret)
+ -- Now apply types heuristic
+ if ret_type == 'string' then
+ return ret,'string'
+ elseif ret_type == 'table' then
+ return ret,'string_list'
+ else
+ return implicit_tostring(ret_type, ret)
+ end
end
end,
}
diff --git a/lualib/lua_selectors/transforms.lua b/lualib/lua_selectors/transforms.lua
index e47fdcec6..bbf5f510a 100644
--- a/lualib/lua_selectors/transforms.lua
+++ b/lualib/lua_selectors/transforms.lua
@@ -132,9 +132,8 @@ local transform_function = {
['types'] = {
['string'] = true
},
- ['map_type'] = 'hash',
+ ['map_type'] = 'string',
['process'] = function(inp, _, args)
-
return common.create_digest(inp, args),'string'
end,
['description'] = [[Create a digest from a string.