From 6dcd2bd6760bdf33c953d89e5c6752a3154bd4ab Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 13 Aug 2019 14:47:25 +0100 Subject: [PATCH] [Fix] Fix more issues with nested messages + tests --- src/libmime/message.c | 27 ++++---- src/libmime/mime_parser.c | 9 +-- test/lua/unit/task.lua | 130 +++++++++++++++++++++++++++++--------- 3 files changed, 119 insertions(+), 47 deletions(-) diff --git a/src/libmime/message.c b/src/libmime/message.c index 7eec503c9..90df43b12 100644 --- a/src/libmime/message.c +++ b/src/libmime/message.c @@ -1412,20 +1412,21 @@ rspamd_message_process (struct rspamd_task *task) PTR_ARRAY_FOREACH (MESSAGE_FIELD (task, parts), i, part) { if (!rspamd_message_process_text_part_maybe (task, part) && part->parsed_data.len > 0) { - const gchar *mb = magic_buffer (task->cfg->libs_ctx->libmagic, - part->parsed_data.begin, - part->parsed_data.len); - - if (mb) { - rspamd_ftok_t srch; - - srch.begin = mb; - srch.len = strlen (mb); - part->detected_ct = rspamd_content_type_parse (srch.begin, - srch.len, - task->task_pool); + if (task->cfg) { + const gchar *mb = magic_buffer (task->cfg->libs_ctx->libmagic, + part->parsed_data.begin, + part->parsed_data.len); + + if (mb) { + rspamd_ftok_t srch; + + srch.begin = mb; + srch.len = strlen (mb); + part->detected_ct = rspamd_content_type_parse (srch.begin, + srch.len, + task->task_pool); + } } - } } diff --git a/src/libmime/mime_parser.c b/src/libmime/mime_parser.c index b40353dca..db945f2ed 100644 --- a/src/libmime/mime_parser.c +++ b/src/libmime/mime_parser.c @@ -1297,15 +1297,16 @@ rspamd_mime_parse_message (struct rspamd_task *task, ret = rspamd_mime_parse_multipart_part (task, npart, nst, err); } else if (sel->flags & RSPAMD_CONTENT_TYPE_MESSAGE) { - g_ptr_array_add (nst->stack, npart); - nst->nesting ++; - ret = rspamd_mime_parse_message (task, npart, nst, err); + if ((ret = rspamd_mime_parse_normal_part (task, npart, nst, err)) + == RSPAMD_MIME_PARSE_OK) { + ret = rspamd_mime_parse_message (task, npart, nst, err); + } } else { ret = rspamd_mime_parse_normal_part (task, npart, nst, err); } - if (part) { + if (part && st->stack->len > 0) { /* Remove message part from the parent stack */ g_ptr_array_remove_index_fast (st->stack, st->stack->len - 1); st->nesting --; diff --git a/test/lua/unit/task.lua b/test/lua/unit/task.lua index 2825a076f..3ec583043 100644 --- a/test/lua/unit/task.lua +++ b/test/lua/unit/task.lua @@ -1,35 +1,11 @@ context("Task processing", function() - local ffi = require("ffi") - local rspamd_util = require("rspamd_util") - local logger = require("rspamd_logger") - local test_dir = string.gsub(debug.getinfo(1).source, "^@(.+/)[^/]+$", "%1") - - local tld_file = string.format('%s/%s', test_dir, "test_tld.dat") - local config = { - options = { - filters = {'spf', 'dkim', 'regexp'}, - url_tld = tld_file, - dns = { - nameserver = {'8.8.8.8'} - }, - }, - logging = { - type = 'console', - level = 'debug' - }, - metric = { - name = 'default', - actions = { - reject = 100500, - }, - unknown_weight = 1 - } - } - + local fun = require("fun") + local rspamd_task = require("rspamd_task") + test("Process a simple task", function() --local cfg = rspamd_util.config_from_ucl(config) --assert_not_nil(cfg) - + local msg = [[ From: <> To: @@ -38,7 +14,101 @@ Content-Type: text/plain Test. ]] - --local obj = rspamd_util.process_message(cfg, msg) - --print(logger.slog("result: %1", obj)) + local res,task = rspamd_task.load_from_string(msg) + assert_true(res, "failed to load message") + task:process_message() + task:destroy() + end) + + local hdrs = [[ +From: <> +To: +Subject: test +]] + local mpart = [[ +Content-Type: multipart/mixed; boundary=XXX +]] + local body = [[ +Content-Type: text/html +Content-Transfer-Encoding: quoted-printable + + + +=0DAttached is your new documents. +
+http:= +//example.com/privacy/XXX/YYY_April_25_2019.doc +
+
+
+Thank you, +
+Haloclaims.co + +]] + test("Process mime nesting: simple", function() + local msg = hdrs .. body + local res,task = rspamd_task.load_from_string(msg) + assert_true(res, "failed to load message") + task:process_message() + assert_rspamd_table_eq({actual = fun.totable(fun.map(function(u) + return u:get_host() + end, task:get_urls())), expect = { + 'evil.com', 'example.com' + }}) + task:destroy() + end) + test("Process mime nesting: multipart", function() + local msg = table.concat{ + hdrs, mpart, '\n', '--XXX\n', body, '\n--XXX--\n' + } + local res,task = rspamd_task.load_from_string(msg) + assert_true(res, "failed to load message") + task:process_message() + assert_rspamd_table_eq({ + actual = fun.totable(fun.map(function(u) + return u:get_host() + end, task:get_urls())), + + expect = { + 'evil.com', 'example.com' + }}) + task:destroy() + end) + test("Process mime nesting: multipart, broken", function() + local msg = table.concat{ + hdrs, mpart, '\n', '--XXX\n', 'garbadge\n', '\n--XXX--\n', '--XXX\n', body + } + local res,task = rspamd_task.load_from_string(msg) + assert_true(res, "failed to load message") + task:process_message() + assert_rspamd_table_eq({ + actual = fun.totable(fun.map(function(u) + return u:get_host() + end, task:get_urls())), + + expect = { + 'evil.com', 'example.com' + }}) + + task:destroy() + end) + test("Process mime nesting: message", function() + local msg = table.concat{ + hdrs, 'Content-Type: message/rfc822\n', '\n', hdrs, body + } + local res,task = rspamd_task.load_from_string(msg) + assert_true(res, "failed to load message") + task:process_message() + assert_rspamd_table_eq({ + actual = fun.totable(fun.map(function(u) + return u:get_host() + end, task:get_urls())), + + expect = { + 'evil.com', 'example.com' + }}) + + task:destroy() end) end) \ No newline at end of file -- 2.39.5