From: Vsevolod Stakhov Date: Fri, 12 Sep 2025 11:26:12 +0000 (+0100) Subject: [Feature] Allow selectors in regexp maps expressions X-Git-Tag: 3.13.0~11^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=346ec89803b8b9e9cfe47cf92e19bc348ece34ee;p=thirdparty%2Frspamd.git [Feature] Allow selectors in regexp maps expressions --- diff --git a/src/lua/lua_config.c b/src/lua/lua_config.c index 7e8ee39f2b..215054b1ca 100644 --- a/src/lua/lua_config.c +++ b/src/lua/lua_config.c @@ -581,7 +581,9 @@ LUA_FUNCTION_DEF(config, replace_regexp); * + `rawheader`: raw header expression * + `body`: raw body regexp * + `url`: url regexp + * + `selector`: selector regexp * - `header`: for header and rawheader regexp means the name of header + * - `selector`: for selector regexp means selector name (registered in scope) * - `pcre_only`: flag regexp as pcre only regexp * @param {string} scope scope name for the regexp * @param {table} params regexp parameters @@ -5012,8 +5014,7 @@ lua_config_register_regexp_scoped(lua_State *L) const char *scope = luaL_checkstring(L, 2); struct rspamd_lua_regexp *re = NULL; rspamd_regexp_t *cache_re; - const char *type_str = NULL, *header_str = NULL; - gsize header_len = 0; + const char *type_str = NULL, *header_str = NULL, *selector_str = NULL; GError *err = NULL; enum rspamd_re_type type = RSPAMD_RE_BODY; gboolean pcre_only = FALSE; @@ -5021,21 +5022,23 @@ lua_config_register_regexp_scoped(lua_State *L) /* * - `scope`*: scope name for the regexp * - `re`* : regular expression object - * - `type`*: type of regular expression: + * - `type`*: type of regular expression: * + `mime`: mime regexp * + `rawmime`: raw mime regexp * + `header`: header regexp * + `rawheader`: raw header expression * + `body`: raw body regexp * + `url`: url regexp + * + `selector`: selector regexp * - `header`: for header and rawheader regexp means the name of header + * - `selector`: for selector regexp means selector name (registered in scope) * - `pcre_only`: allow merely pcre for this regexp */ if (cfg != NULL && scope != NULL) { if (!rspamd_lua_parse_table_arguments(L, 3, &err, RSPAMD_LUA_PARSE_ARGUMENTS_DEFAULT, - "*re=U{regexp};*type=S;header=S;pcre_only=B", - &re, &type_str, &header_str, &pcre_only)) { + "*re=U{regexp};*type=S;header=S;selector=S;pcre_only=B", + &re, &type_str, &header_str, &selector_str, &pcre_only)) { msg_err_config("cannot get parameters list: %e", err); if (err) { @@ -5058,13 +5061,22 @@ lua_config_register_regexp_scoped(lua_State *L) rspamd_regexp_get_flags(re->re) | RSPAMD_REGEXP_FLAG_PCRE_ONLY); } - if (header_str != NULL) { + const char *type_data = NULL; + gsize type_len = 0; + + if (header_str != NULL && + (type == RSPAMD_RE_HEADER || type == RSPAMD_RE_RAWHEADER || type == RSPAMD_RE_MIMEHEADER)) { /* Include the last \0 */ - header_len = strlen(header_str) + 1; + type_len = strlen(header_str) + 1; + type_data = header_str; + } + else if (selector_str != NULL && type == RSPAMD_RE_SELECTOR) { + type_len = strlen(selector_str) + 1; + type_data = selector_str; } cache_re = rspamd_re_cache_add_scoped(&cfg->re_cache, scope, re->re, type, - (gpointer) header_str, header_len, -1); + (gpointer) type_data, type_len, -1); /* * XXX: here are dragons! diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c index 0b1473b61c..5085e6c2ab 100644 --- a/src/lua/lua_task.c +++ b/src/lua/lua_task.c @@ -6293,29 +6293,33 @@ lua_task_process_regexp(lua_State *L) struct rspamd_task *task = lua_check_task(L, 1); struct rspamd_lua_regexp *re = NULL; gboolean strong = FALSE; - const char *type_str = NULL, *header_str = NULL; - gsize header_len = 0; + const char *type_str = NULL, *header_str = NULL, *selector_str = NULL; + gsize header_len = 0, selector_len = 0; GError *err = NULL; int ret = 0; enum rspamd_re_type type = RSPAMD_RE_BODY; /* * - `re`* : regular expression object - * - `type`*: type of regular expression: + * - `type`*: type of regular expression: * + `mime`: mime regexp * + `rawmime`: raw mime regexp * + `header`: header regexp * + `rawheader`: raw header expression * + `body`: raw body regexp * + `url`: url regexp - * - `header`: for header and rawheader regexp means the name of header + * + `selector`: selector regexp + * - `header`: for header/rawheader/mimeheader regexp means the name of header + * - `selector`: for selector regexp means the selector name (registered in scope) * - `strong`: case sensitive match for headers */ if (task != NULL) { if (!rspamd_lua_parse_table_arguments(L, 2, &err, RSPAMD_LUA_PARSE_ARGUMENTS_DEFAULT, - "*re=U{regexp};*type=S;header=V;strong=B", - &re, &type_str, &header_len, &header_str, + "*re=U{regexp};*type=S;header=V;selector=V;strong=B", + &re, &type_str, + &header_len, &header_str, + &selector_len, &selector_str, &strong)) { msg_err_task("cannot get parameters list: %e", err); @@ -6328,13 +6332,30 @@ lua_task_process_regexp(lua_State *L) else { type = rspamd_re_cache_type_from_string(type_str); - if ((type == RSPAMD_RE_HEADER || type == RSPAMD_RE_RAWHEADER) && header_str == NULL) { + if ((type == RSPAMD_RE_HEADER || type == RSPAMD_RE_RAWHEADER || type == RSPAMD_RE_MIMEHEADER) && header_str == NULL) { msg_err_task( "header argument is mandatory for header/rawheader regexps"); } else { + const char *type_data = NULL; + gsize type_len = 0; + + if (type == RSPAMD_RE_HEADER || type == RSPAMD_RE_RAWHEADER || type == RSPAMD_RE_MIMEHEADER) { + type_data = header_str; + type_len = header_len; + } + else if (type == RSPAMD_RE_SELECTOR) { + if (selector_str == NULL) { + msg_err_task("selector argument is mandatory for selector regexps"); + } + else { + type_data = selector_str; + type_len = selector_len; + } + } + ret = rspamd_re_cache_process(task, re->re, type, - (gpointer) header_str, header_len, strong); + (gpointer) type_data, type_len, strong); } } } diff --git a/src/plugins/lua/multimap.lua b/src/plugins/lua/multimap.lua index 8bb62bef13..7e93ba058f 100644 --- a/src/plugins/lua/multimap.lua +++ b/src/plugins/lua/multimap.lua @@ -62,8 +62,8 @@ local function parse_multimap_value(parse_rule, p_ret) (digit ^ 1) -- Matches: 55.97, -90.8, .9 - number.decimal = (number.integer * -- Integer - (number.fractional ^ -1)) + -- Fractional + number.decimal = (number.integer * -- Integer + (number.fractional ^ -1)) + -- Fractional (lpeg.S("+-") * number.fractional) -- Completely fractional number local sym_start = lpeg.R("az", "AZ") + lpeg.S("_") @@ -98,7 +98,7 @@ local function parse_multimap_value(parse_rule, p_ret) else if p_ret ~= '' then rspamd_logger.infox(rspamd_config, '%s: cannot parse string "%s"', - parse_rule.symbol, p_ret) + parse_rule.symbol, p_ret) end return true, nil, 1.0, {} @@ -183,6 +183,19 @@ local function create_sa_atom_function(name, re, match_type, opts) ret = process_re_match(re, task, 'body') elseif match_type == 'uri' then ret = process_re_match(re, task, 'url') + elseif match_type == 'selector' then + -- For selector regexps, use structured call with explicit selector field + local params = { + re = re, + type = 'selector', + selector = opts.selector, + strong = false, + } + if type(jit) == 'table' then + ret = task:process_regexp(params) + else + ret = task:process_regexp(params) + end else -- Default to body ret = process_re_match(re, task, 'sabody') @@ -259,7 +272,7 @@ local function process_sa_line(rule, line) } lua_util.debugm(N, rspamd_config, 'added SA header atom: %s for header %s (scope: %s)', - atom_name, header_name, scope_name) + atom_name, header_name, scope_name) end end elseif words[1] == 'body' then @@ -378,6 +391,69 @@ local function process_sa_line(rule, line) lua_util.debugm(N, rspamd_config, 'added SA full atom: %s (scope: %s)', atom_name, scope_name) end end + elseif words[1] == 'selector' then + -- selector SYMBOL selector_pipeline =~ /regexp/flags + -- selector pipeline can contain spaces; find operator position first + if #words >= 4 then + local atom_name = words[2] + local op_idx = nil + for i = 4, #words do + if words[i] == '=~' or words[i] == '!~' then + op_idx = i + break + end + end + if not op_idx then + return + end + local selector_pipeline_tbl = {} + for i = 3, op_idx - 1 do + selector_pipeline_tbl[#selector_pipeline_tbl + 1] = words[i] + end + local selector_pipeline = table.concat(selector_pipeline_tbl, ' ') + local re_expr = words_to_sa_re(words, op_idx) + + -- Skip =~ or !~ + re_expr = string.gsub(re_expr, '^[!=]~%s*', '') + + local re = parse_sa_regexp(atom_name, re_expr) + if re then + -- Register selector and regexp in cache scope to use regexp-cache + hyperscan + local ok = rspamd_config:register_re_selector_scoped(scope_name, atom_name, selector_pipeline, "", false) + if not ok then + rspamd_logger.errx(rspamd_config, 'selector atom %s has invalid selector (registration failed): %s', + atom_name, selector_pipeline) + return + end + + rspamd_config:register_regexp_scoped(scope_name, { + re = re, + type = 'selector', + selector = atom_name, + pcre_only = false, + }) + + re:set_limit(0) + re:set_max_hits(1) + + local negate = (words[op_idx] == '!~') + sa_atoms[atom_name] = create_sa_atom_function(atom_name, re, 'selector', { + selector = atom_name, + strong = false, + negate = negate, + }) + + -- Track atom state consistent with scoped regexps + regexp_rules_symbol_states[atom_name] = { + state = 'loading', + rule_name = rule_name, + type = 'atom' + } + + lua_util.debugm(N, rspamd_config, 'added SA selector atom: %s for selector %s (scope: %s)', + atom_name, selector_pipeline, scope_name) + end + end elseif words[1] == 'meta' then -- meta SYMBOL expression if #words >= 3 then @@ -444,10 +520,14 @@ local function gen_sa_process_atom_cb(task, rule_name) if state_info.state == 'orphaned' or state_info.state == 'loading' then -- Double-check by looking at scope loaded state local scope_loaded = false - for _, rule in ipairs(rules) do - if rule.symbol == state_info.rule_name and rule.scope_name then - scope_loaded = rspamd_config:is_regexp_scope_loaded(rule.scope_name) - break + if state_info.scope_optional then + scope_loaded = true + else + for _, rule in ipairs(rules) do + if rule.symbol == state_info.rule_name and rule.scope_name then + scope_loaded = rspamd_config:is_regexp_scope_loaded(rule.scope_name) + break + end end end @@ -455,7 +535,7 @@ local function gen_sa_process_atom_cb(task, rule_name) -- Update state to available if scope is loaded and atom exists state_info.state = 'available' lua_util.debugm(N, task, 'regexp_rules atom %s was %s, but scope is loaded - marking as available', - atom, state_info.state) + atom, state_info.state) else lua_util.debugm(N, task, 'regexp_rules atom %s is %s, returning 0', atom, state_info.state) return 0 @@ -507,10 +587,10 @@ create_sa_meta_callback = function(meta_rule) -- Update state to available if scope is loaded and meta rule exists state_info.state = 'available' lua_util.debugm(N, task, 'regexp_rules meta %s was %s, but scope is loaded - marking as available', - meta_rule.symbol, state_info.state) + meta_rule.symbol, state_info.state) else lua_util.debugm(N, task, 'regexp_rules meta %s is %s, skipping execution', - meta_rule.symbol, state_info.state) + meta_rule.symbol, state_info.state) return 0 end end @@ -532,8 +612,8 @@ create_sa_meta_callback = function(meta_rule) if not (already_processed and already_processed['default']) then local expression = rspamd_expression.create(meta_rule.expression, - parse_sa_atom, - rspamd_config:get_mempool()) + parse_sa_atom, + rspamd_config:get_mempool()) if not expression then rspamd_logger.errx(rspamd_config, 'Cannot parse SA meta expression: %s', meta_rule.expression) return @@ -544,11 +624,11 @@ create_sa_meta_callback = function(meta_rule) if res > 0 then local filtered_trace = fun.totable(fun.take_n(5, - fun.map(function(elt) - return elt:gsub('^__', '') - end, fun.filter(exclude_sym_filter, trace)))) + fun.map(function(elt) + return elt:gsub('^__', '') + end, fun.filter(exclude_sym_filter, trace)))) lua_util.debugm(N, task, 'SA meta %s matched with result: %s; trace %s; filtered trace %s', - meta_rule.symbol, res, trace, filtered_trace) + meta_rule.symbol, res, trace, filtered_trace) task:insert_result_named(cur_res, meta_rule.symbol, 1.0, filtered_trace) end @@ -576,14 +656,14 @@ end -- Initialize SA meta rules after all atoms are processed local function finalize_sa_rules() lua_util.debugm(N, rspamd_config, 'Finalizing SA rules - processing %s meta rules', - fun.length(sa_meta_rules)) + fun.length(sa_meta_rules)) for meta_name, meta_rule in pairs(sa_meta_rules) do local score = sa_scores[meta_name] or 1.0 local description = sa_descriptions[meta_name] or ('multimap symbol ' .. meta_name) lua_util.debugm(N, rspamd_config, 'Registering SA meta rule %s (score: %s, expression: %s)', - meta_name, score, meta_rule.expression) + meta_name, score, meta_rule.expression) local id = rspamd_config:register_symbol({ name = meta_name, @@ -595,7 +675,7 @@ local function finalize_sa_rules() }) lua_util.debugm(N, rspamd_config, 'Successfully registered SA meta symbol %s with id %s (callback attached)', - meta_name, id) + meta_name, id) rspamd_config:set_metric_symbol({ name = meta_name, @@ -619,7 +699,7 @@ local function finalize_sa_rules() end lua_util.debugm(N, rspamd_config, 'registered SA meta symbol: %s (score: %s)', - meta_name, score) + meta_name, score) end -- Mark orphaned symbols - only check meta symbols (not atoms) since atoms are just expression parts @@ -632,7 +712,7 @@ local function finalize_sa_rules() end lua_util.debugm(N, rspamd_config, 'SA rules finalization complete: registered %s meta rules with callbacks', - fun.length(sa_meta_rules)) + fun.length(sa_meta_rules)) end -- Helper function to get regexp_rules symbol state statistics (only meta symbols, not atoms) @@ -674,7 +754,7 @@ local function sync_regexp_rules_symbol_states() end lua_util.debugm(N, rspamd_config, 'Scope %s is loaded, marked %s symbols as available', - rule.scope_name, updated_count) + rule.scope_name, updated_count) else lua_util.debugm(N, rspamd_config, 'Scope %s is not loaded', rule.scope_name) end @@ -683,7 +763,7 @@ local function sync_regexp_rules_symbol_states() local stats = get_regexp_rules_symbol_stats() lua_util.debugm(N, rspamd_config, 'Symbol state stats after sync: available=%s, loading=%s, orphaned=%s, total=%s', - stats.available, stats.loading, stats.orphaned, stats.total) + stats.available, stats.loading, stats.orphaned, stats.total) end -- Optional cleanup function to remove old orphaned symbols (can be called periodically) @@ -1130,19 +1210,19 @@ local function multimap_query_redis(key, task, value, callback) local function redis_map_cb(err, data) lua_util.debugm(N, task, 'got reply from Redis when trying to get key %s: err=%s, data=%s', - key, err, data) + key, err, data) if not err and type(data) ~= 'userdata' then callback(data) end end return rspamd_redis_make_request(task, - redis_params, -- connect params - key, -- hash key - false, -- is write - redis_map_cb, --callback - cmd, -- command - srch -- arguments + redis_params, -- connect params + key, -- hash key + false, -- is write + redis_map_cb, --callback + cmd, -- command + srch -- arguments ) end @@ -1154,9 +1234,9 @@ local function multimap_callback(task, rule) local function get_key_callback(ret, err_or_data, err_code) lua_util.debugm(N, task, 'got return "%s" (err code = %s) for multimap %s', - err_or_data, - err_code, - rule.symbol) + err_or_data, + err_code, + rule.symbol) if ret then if type(err_or_data) == 'table' then @@ -1168,12 +1248,12 @@ local function multimap_callback(task, rule) end elseif err_code ~= 404 then rspamd_logger.infox(task, "map %s: get key returned error %s: %s", - rule.symbol, err_code, err_or_data) + rule.symbol, err_code, err_or_data) end end lua_util.debugm(N, task, 'check value %s for multimap %s', value, - rule.symbol) + rule.symbol) local ret = false @@ -1212,8 +1292,8 @@ local function multimap_callback(task, rule) if rule.symbols_set then if not rule.symbols_set[symbol] then rspamd_logger.infox(task, 'symbol %s is not registered for map %s, ' .. - 'replace it with just %s', - symbol, rule.symbol, rule.symbol) + 'replace it with just %s', + symbol, rule.symbol, rule.symbol) symbol = rule.symbol end elseif rule.disable_multisymbol then @@ -1283,7 +1363,7 @@ local function multimap_callback(task, rule) if fn then local filtered_value = fn(task, r.filter, value, r) lua_util.debugm(N, task, 'apply filter %s for rule %s: %s -> %s', - r.filter, r.symbol, value, filtered_value) + r.filter, r.symbol, value, filtered_value) value = filtered_value end end @@ -1430,12 +1510,12 @@ local function multimap_callback(task, rule) if not res or res == 0 then lua_util.debugm(N, task, 'condition is false for %s', - rule.symbol) + rule.symbol) return else lua_util.debugm(N, task, 'condition is true for %s: %s', - rule.symbol, - trace) + rule.symbol, + trace) end end @@ -1452,18 +1532,18 @@ local function multimap_callback(task, rule) local to_resolve = ip_to_rbl(ip, rule['map']) local function dns_cb(_, _, results, err) lua_util.debugm(N, rspamd_config, - 'resolve() finished: results=%1, err=%2, to_resolve=%3', - results, err, to_resolve) + 'resolve() finished: results=%1, err=%2, to_resolve=%3', + results, err, to_resolve) if err and (err ~= 'requested record is not found' and - err ~= 'no records with this name') then + err ~= 'no records with this name') then rspamd_logger.errx(task, 'error looking up %s: %s', to_resolve, results) elseif results then task:insert_result(rule['symbol'], 1, rule['map']) if rule.action then task:set_pre_result(rule['action'], - 'Matched map: ' .. rule['symbol'], N) + 'Matched map: ' .. rule['symbol'], N) end end end @@ -1629,7 +1709,7 @@ local function multimap_callback(task, rule) if ext then local fake_fname = string.format('detected.%s', ext) lua_util.debugm(N, task, 'detected filename %s', - fake_fname) + fake_fname) match_filename(rule, fake_fname) end end @@ -1702,7 +1782,7 @@ local function multimap_callback(task, rule) if ret and ret ~= 0 then for n, t in pairs(trace) do insert_results(t.value, string.format("%s=%s", - n, t.matched)) + n, t.matched)) end end end, @@ -1710,7 +1790,7 @@ local function multimap_callback(task, rule) -- For regexp_rules, the meta rules are registered as separate symbols -- This is just a placeholder callback lua_util.debugm(N, task, 'Regexp rules callback for %s - meta rules are registered as separate symbols', - rule.symbol) + rule.symbol) end, } @@ -1739,7 +1819,7 @@ local function multimap_on_load_gen(rule) if r and symbol and not known_symbols[symbol] then lua_util.debugm(N, rspamd_config, "%s: adding new symbol %s (score = %s), triggered by %s", - rule.symbol, symbol, score, key) + rule.symbol, symbol, score, key) rspamd_config:register_symbol { name = symbol, parent = rule.callback_id, @@ -1765,22 +1845,22 @@ local function add_multimap_rule(key, newrule) if rule['regexp'] then if rule['multi'] then rule.map_obj = lua_maps.map_add_from_ucl(rule.map, 'regexp_multi', - rule.description) + rule.description) else rule.map_obj = lua_maps.map_add_from_ucl(rule.map, 'regexp', - rule.description) + rule.description) end elseif rule['glob'] then if rule['multi'] then rule.map_obj = lua_maps.map_add_from_ucl(rule.map, 'glob_multi', - rule.description) + rule.description) else rule.map_obj = lua_maps.map_add_from_ucl(rule.map, 'glob', - rule.description) + rule.description) end else rule.map_obj = lua_maps.map_add_from_ucl(rule.map, 'hash', - rule.description) + rule.description) end end @@ -1821,7 +1901,7 @@ local function add_multimap_rule(key, newrule) end if not newrule['description'] then newrule['description'] = string.format('multimap, type %s: %s', newrule['type'], - newrule['symbol']) + newrule['symbol']) end if newrule['type'] == 'mempool' and not newrule['variable'] then rspamd_logger.errx(rspamd_config, 'mempool map requires variable') @@ -1833,11 +1913,11 @@ local function add_multimap_rule(key, newrule) return nil else local selector = lua_selectors.create_selector_closure( - rspamd_config, newrule['selector'], newrule['delimiter'] or "") + rspamd_config, newrule['selector'], newrule['delimiter'] or "") if not selector then rspamd_logger.errx(rspamd_config, 'selector map has invalid selector: "%s", symbol: %s', - newrule['selector'], newrule['symbol']) + newrule['selector'], newrule['symbol']) return nil end @@ -1848,7 +1928,7 @@ local function add_multimap_rule(key, newrule) string.find(newrule['map'], '^redis://.*$') then if not redis_params then rspamd_logger.infox(rspamd_config, 'no redis servers are specified, ' .. - 'cannot add redis map %s: %s', newrule['symbol'], newrule['map']) + 'cannot add redis map %s: %s', newrule['symbol'], newrule['map']) return nil end @@ -1861,17 +1941,17 @@ local function add_multimap_rule(key, newrule) string.find(newrule['map'], '^redis%+selector://.*$') then if not redis_params then rspamd_logger.infox(rspamd_config, 'no redis servers are specified, ' .. - 'cannot add redis map %s: %s', newrule['symbol'], newrule['map']) + 'cannot add redis map %s: %s', newrule['symbol'], newrule['map']) return nil end local selector_str = string.match(newrule['map'], '^redis%+selector://(.*)$') local selector = lua_selectors.create_selector_closure( - rspamd_config, selector_str, newrule['delimiter'] or "") + rspamd_config, selector_str, newrule['delimiter'] or "") if not selector then rspamd_logger.errx(rspamd_config, 'redis selector map has invalid selector: "%s", symbol: %s', - selector_str, newrule['symbol']) + selector_str, newrule['symbol']) return nil end @@ -1880,12 +1960,12 @@ local function add_multimap_rule(key, newrule) elseif newrule.type == 'combined' then local lua_maps_expressions = require "lua_maps_expressions" newrule.combined = lua_maps_expressions.create(rspamd_config, - { - rules = newrule.rules, - expression = newrule.expression, - description = newrule.description, - on_load = newrule.dynamic_symbols and multimap_on_load_gen(newrule) or nil, - }, N, 'Combined map for ' .. newrule.symbol) + { + rules = newrule.rules, + expression = newrule.expression, + description = newrule.description, + on_load = newrule.dynamic_symbols and multimap_on_load_gen(newrule) or nil, + }, N, 'Combined map for ' .. newrule.symbol) if not newrule.combined then rspamd_logger.errx(rspamd_config, 'cannot add combined map for %s', newrule.symbol) else @@ -1940,7 +2020,7 @@ local function add_multimap_rule(key, newrule) if state_info.rule_name == newrule.symbol then state_info.state = 'loading' lua_util.debugm(N, rspamd_config, 'marked regexp_rules symbol %s as loading for scope %s reload', - symbol, scope_name) + symbol, scope_name) end end @@ -1956,7 +2036,7 @@ local function add_multimap_rule(key, newrule) sa_atoms[symbol] = nil sa_meta_rules[symbol] = nil lua_util.debugm(N, rspamd_config, 'cleared regexp_rules symbol %s for scope %s reload', - symbol, scope_name) + symbol, scope_name) end -- The scope will be created by process_sa_line when first regexp is added @@ -1966,7 +2046,7 @@ local function add_multimap_rule(key, newrule) end process_sa_line(newrule, line) end, - by_line = true, -- Process line by line + by_line = true, -- Process line by line opaque_data = false, -- Use plain strings }) @@ -2002,7 +2082,7 @@ local function add_multimap_rule(key, newrule) -- Trigger hyperscan compilation for this updated scope newrule.map_obj:trigger_hyperscan_compilation() lua_util.debugm(N, rspamd_config, 'triggered hyperscan compilation for scope %s after map loading', - scope_name) + scope_name) else lua_util.debugm(N, rspamd_config, 'regexp scope %s not created (empty map)', scope_name) end @@ -2016,7 +2096,7 @@ local function add_multimap_rule(key, newrule) -- Promote symcache resort after dynamic symbol registration rspamd_config:promote_symbols_cache_resort() lua_util.debugm(N, rspamd_config, 'promoted symcache resort after loading SA rules from map %s', - newrule.symbol) + newrule.symbol) end) end @@ -2024,21 +2104,21 @@ local function add_multimap_rule(key, newrule) -- Mark this rule as using SA functionality newrule.uses_sa = true lua_util.debugm(N, rspamd_config, 'created regexp_rules map %s with scope: %s', - newrule.symbol, scope_name) + newrule.symbol, scope_name) ret = true else rspamd_logger.warnx(rspamd_config, 'Cannot add SA-style rule: map doesn\'t exists: %s', - newrule['map']) + newrule['map']) end else if newrule['type'] == 'ip' then newrule.map_obj = lua_maps.map_add_from_ucl(newrule.map, 'radix', - newrule.description) + newrule.description) if newrule.map_obj then ret = true else rspamd_logger.warnx(rspamd_config, 'Cannot add rule: map doesn\'t exists: %s', - newrule['map']) + newrule['map']) end elseif newrule['type'] == 'received' then if type(newrule['flags']) == 'table' and newrule['flags'][1] then @@ -2054,12 +2134,12 @@ local function add_multimap_rule(key, newrule) local filter = newrule['filter'] or 'real_ip' if filter == 'real_ip' or filter == 'from_ip' then newrule.map_obj = lua_maps.map_add_from_ucl(newrule.map, 'radix', - newrule.description) + newrule.description) if newrule.map_obj then ret = true else rspamd_logger.warnx(rspamd_config, 'Cannot add rule: map doesn\'t exists: %s', - newrule['map']) + newrule['map']) end else multimap_load_kv_map(newrule) @@ -2068,13 +2148,13 @@ local function add_multimap_rule(key, newrule) ret = true else rspamd_logger.warnx(rspamd_config, 'Cannot add rule: map doesn\'t exists: %s', - newrule['map']) + newrule['map']) end end elseif known_generic_types[newrule.type] then if newrule.filter == 'ip_addr' then newrule.map_obj = lua_maps.map_add_from_ucl(newrule.map, 'radix', - newrule.description) + newrule.description) elseif not newrule.combined then multimap_load_kv_map(newrule) end @@ -2083,13 +2163,13 @@ local function add_multimap_rule(key, newrule) ret = true else rspamd_logger.warnx(rspamd_config, 'Cannot add rule: map doesn\'t exists: %s', - newrule['map']) + newrule['map']) end elseif newrule['type'] == 'dnsbl' then ret = true else rspamd_logger.errx(rspamd_config, 'cannot add rule %s: invalid type %s', - key, newrule['type']) + key, newrule['type']) end end @@ -2126,13 +2206,13 @@ local function add_multimap_rule(key, newrule) end local expression = rspamd_expression.create(newrule['require_symbols'], - { parse_atom, process_atom }, rspamd_config:get_mempool()) + { parse_atom, process_atom }, rspamd_config:get_mempool()) if expression then newrule['expression'] = expression fun.each(function(v) lua_util.debugm(N, rspamd_config, 'add dependency %s -> %s', - newrule['symbol'], v) + newrule['symbol'], v) rspamd_config:register_dependency(newrule['symbol'], v) end, atoms) end @@ -2177,7 +2257,7 @@ if opts and type(opts) == 'table' then rspamd_logger.errx(rspamd_config, 'cannot add rule: "' .. k .. '"') else rspamd_logger.infox(rspamd_config, 'added multimap rule: %s (%s)', - k, rule.type) + k, rule.type) table.insert(rules, rule) end end