aboutsummaryrefslogtreecommitdiffstats
path: root/src/libmime/mime_parser.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2018-10-30 14:49:09 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2018-10-30 14:49:09 +0000
commite6de9872c29930c3fe147869b7e6011c48fe96fd (patch)
tree575179a11697e89d21e04d1b79fbd006bc47428d /src/libmime/mime_parser.c
parenta8b22f9aacad391cdaa865039f38a13f622fdbc3 (diff)
downloadrspamd-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.c64
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);
}