diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-10-30 14:49:09 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-10-30 14:49:09 +0000 |
commit | e6de9872c29930c3fe147869b7e6011c48fe96fd (patch) | |
tree | 575179a11697e89d21e04d1b79fbd006bc47428d /src/libmime/mime_parser.c | |
parent | a8b22f9aacad391cdaa865039f38a13f622fdbc3 (diff) | |
download | rspamd-e6de9872c29930c3fe147869b7e6011c48fe96fd.tar.gz rspamd-e6de9872c29930c3fe147869b7e6011c48fe96fd.zip |
[Feature] Detect orphaned parts and attach them to message
Diffstat (limited to 'src/libmime/mime_parser.c')
-rw-r--r-- | src/libmime/mime_parser.c | 64 |
1 files changed, 59 insertions, 5 deletions
diff --git a/src/libmime/mime_parser.c b/src/libmime/mime_parser.c index 0365a02b2..c1c5c0889 100644 --- a/src/libmime/mime_parser.c +++ b/src/libmime/mime_parser.c @@ -562,17 +562,20 @@ rspamd_mime_process_multipart_node (struct rspamd_task *task, hdr_pos = rspamd_string_find_eoh (&str, &body_pos); } - if (multipart->specific.mp.children == NULL) { - multipart->specific.mp.children = g_ptr_array_sized_new (2); - } - npart = rspamd_mempool_alloc0 (task->task_pool, sizeof (struct rspamd_mime_part)); npart->parent_part = multipart; npart->raw_headers = g_hash_table_new_full (rspamd_strcase_hash, rspamd_strcase_equal, NULL, rspamd_ptr_array_free_hard); npart->headers_order = g_queue_new (); - g_ptr_array_add (multipart->specific.mp.children, npart); + + if (multipart) { + if (multipart->specific.mp.children == NULL) { + multipart->specific.mp.children = g_ptr_array_sized_new (2); + } + + g_ptr_array_add (multipart->specific.mp.children, npart); + } if (hdr_pos > 0 && hdr_pos < str.len) { npart->raw_headers_str = str.str; @@ -1262,6 +1265,57 @@ rspamd_mime_parse_message (struct rspamd_task *task, st->nesting --; } + /* Process leftovers for boundaries */ + if (nst->boundaries) { + struct rspamd_mime_boundary *boundary, *start_boundary = NULL, + *end_boundary = NULL; + goffset cur_offset = st->pos - st->start, + end_offset = st->end - st->start; + guint sel_idx = 0; + + for (;;) { + start_boundary = NULL; + + for (i = sel_idx; i < nst->boundaries->len; i++) { + boundary = &g_array_index (st->boundaries, + struct rspamd_mime_boundary, i); + + if (boundary->start > cur_offset && + boundary->boundary < end_offset && + !RSPAMD_BOUNDARY_IS_CLOSED (boundary)) { + start_boundary = boundary; + sel_idx = i; + break; + } + } + + if (start_boundary) { + const gchar *start, *end; + + if (nst->boundaries->len > sel_idx + 1) { + end_boundary = &g_array_index (st->boundaries, + struct rspamd_mime_boundary, sel_idx + 1); + end = st->start + end_boundary->boundary; + } + else { + end = st->end; + } + + sel_idx ++; + + start = st->start + start_boundary->start; + + if ((ret = rspamd_mime_process_multipart_node (task, st, + NULL, start, end, err)) != RSPAMD_MIME_PARSE_OK) { + return ret; + } + } + else { + break; + } + } + } + if (nst != st) { rspamd_mime_parse_stack_free (nst); } |