]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Detect orphaned parts and attach them to message
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 30 Oct 2018 14:49:09 +0000 (14:49 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 30 Oct 2018 14:49:09 +0000 (14:49 +0000)
src/libmime/mime_parser.c

index 0365a02b25cc12018a963b0e4ccc5e45edfee6ae..c1c5c088922814241f696d5a79587cf33c565439 100644 (file)
@@ -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);
        }