From: Vsevolod Stakhov Date: Thu, 12 Feb 2026 10:00:14 +0000 (+0000) Subject: [Fix] Fix issues in logstats/mapstats from code review X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c921f72995e388078c84580d9dd8766ed76d8187;p=thirdparty%2Frspamd.git [Fix] Fix issues in logstats/mapstats from code review - Shell-quote paths in io.popen() to prevent injection - Fix typo: correllations -> correlations in JSON output - Pre-compile ignored symbol regexes instead of recompiling per call - Deduplicate score change output logic in logstats - Use native rspamd_ip equality instead of string comparison in mapstats --- diff --git a/lualib/lua_log_utils.lua b/lualib/lua_log_utils.lua index 03dcdeb3a6..319031c56a 100644 --- a/lualib/lua_log_utils.lua +++ b/lualib/lua_log_utils.lua @@ -135,11 +135,15 @@ function exports.normalized_time(s) return s end +local function shell_quote(s) + return "'" .. s:gsub("'", "'\\''") .. "'" +end + function exports.open_log_file(path) local ext = path:match('%.([^%.]+)$') local dc = decompressor[ext] if dc then - return io.popen(dc .. ' ' .. path, 'r') + return io.popen(dc .. ' ' .. shell_quote(path), 'r') else return io.open(path, 'r') end diff --git a/lualib/rspamadm/logstats.lua b/lualib/rspamadm/logstats.lua index 981e3ad123..31517136be 100644 --- a/lualib/rspamadm/logstats.lua +++ b/lualib/rspamadm/logstats.lua @@ -107,10 +107,20 @@ parser:option "-x --exclude-logs" parser:flag "--json" :description "Print JSON output" -local function is_ignored(sym, ignored_list) +local function compile_ignored(ignored_list) + local compiled = {} for _, ex in ipairs(ignored_list) do local re = rspamd_regexp.create('^' .. ex .. '$') - if re and re:match(sym) then + if re then + table.insert(compiled, re) + end + end + return compiled +end + +local function is_ignored(sym, ignored_compiled) + for _, re in ipairs(ignored_compiled) do + if re:match(sym) then return true end end @@ -211,7 +221,7 @@ local function handler(args) local symbols_search = res['symbol'] or {} local symbols_bidir = res['symbol_bidir'] or {} local symbols_exclude = res['exclude'] or {} - local symbols_ignored = res['ignore'] or {} + local symbols_ignored = compile_ignored(res['ignore'] or {}) local symbols_groups = res['group'] or {} local symbols_mult = parse_mult_options(res['mult'] or {}) local diff_alpha = res['alpha_score'] @@ -525,7 +535,7 @@ local function handler(args) local sym_prob = r.hits / total corr_data[cs] = corr_prob / sym_prob end - sym_data.correllations = corr_data + sym_data.correlations = corr_data end result.symbols[s] = sym_data @@ -566,27 +576,23 @@ local function handler(args) local jchp = (total_junk > 0) and (r.junk_change / total_junk * 100.0) or 0 if r.weight ~= 0 then + local spam_desc, junk_desc if r.weight > 0 then - io.write(string.format( - "\nSpam changes (ham/junk -> spam): %6d/%-6d (%7.3f%%)\n" .. - "Spam changes / total spam hits: %6d/%-6d (%7.3f%%)\n" .. - "Junk changes (ham -> junk): %6d/%-6d (%7.3f%%)\n" .. - "Junk changes / total junk hits: %6d/%-6d (%7.3f%%)\n", - r.spam_change, th, (r.spam_change / th * 100), - r.spam_change, total_spam, schp, - r.junk_change, th, (r.junk_change / th * 100), - r.junk_change, total_junk, jchp)) + spam_desc = "Spam changes (ham/junk -> spam)" + junk_desc = "Junk changes (ham -> junk)" else - io.write(string.format( - "\nSpam changes (spam -> junk/ham): %6d/%-6d (%7.3f%%)\n" .. - "Spam changes / total spam hits : %6d/%-6d (%7.3f%%)\n" .. - "Junk changes (junk -> ham) : %6d/%-6d (%7.3f%%)\n" .. - "Junk changes / total junk hits : %6d/%-6d (%7.3f%%)\n", - r.spam_change, th, (r.spam_change / th * 100), - r.spam_change, total_spam, schp, - r.junk_change, th, (r.junk_change / th * 100), - r.junk_change, total_junk, jchp)) + spam_desc = "Spam changes (spam -> junk/ham)" + junk_desc = "Junk changes (junk -> ham) " end + io.write(string.format( + "\n%s: %6d/%-6d (%7.3f%%)\n" .. + "Spam changes / total spam hits: %6d/%-6d (%7.3f%%)\n" .. + "%s: %6d/%-6d (%7.3f%%)\n" .. + "Junk changes / total junk hits: %6d/%-6d (%7.3f%%)\n", + spam_desc, r.spam_change, th, (r.spam_change / th * 100), + r.spam_change, total_spam, schp, + junk_desc, r.junk_change, th, (r.junk_change / th * 100), + r.junk_change, total_junk, jchp)) end if correlations then diff --git a/lualib/rspamadm/mapstats.lua b/lualib/rspamadm/mapstats.lua index 43b386f2cd..8fbcc81ce0 100644 --- a/lualib/rspamadm/mapstats.lua +++ b/lualib/rspamadm/mapstats.lua @@ -229,13 +229,13 @@ local function ip_within(ip_obj, cidr_str) if not ip_masked or not cidr_masked then return false end - return tostring(ip_masked) == tostring(cidr_masked) + return ip_masked == cidr_masked else local cidr_ip = rspamd_ip.from_string(cidr_str) if not cidr_ip or not cidr_ip:is_valid() then return false end - return tostring(ip_obj) == tostring(cidr_ip) + return ip_obj == cidr_ip end end