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);
g_ptr_array_add (multipart->children, npart);
if (hdr_pos > 0 && hdr_pos < str.len) {
-
npart->raw_headers_str = str.str;
- npart->raw_headers_len = str.len;
+ npart->raw_headers_len = hdr_pos;
npart->raw_data.begin = start + body_pos;
npart->raw_data.len = (end - start) - body_pos;
if (task->raw_headers_content.len > 0) {
- rspamd_mime_headers_process (task, task->raw_headers,
+ rspamd_mime_headers_process (task, npart->raw_headers,
npart->raw_headers_str,
npart->raw_headers_len,
TRUE);
}
- hdrs = rspamd_message_get_header_from_hash (st->cur_part->raw_headers,
+ hdrs = rspamd_message_get_header_from_hash (npart->raw_headers,
task->task_pool,
"Content-Type", FALSE);
if (sel == NULL) {
/* TODO: assume part as octet-stream */
+ g_set_error (err, RSPAMD_MIME_QUARK, EINVAL, "no content type");
return FALSE;
}
task = cb->task;
+ if (cb->st->pos && pos <= cb->st->pos) {
+ /* Already processed */
+ return 0;
+ }
+
/* Now check boundary */
if (!cb->part_start) {
if (cb->cur_boundary) {
- if (match_pos + cb->cur_boundary->len > len) {
- if (memcmp (pos, cb->cur_boundary->begin, cb->cur_boundary->len) != 0) {
+ if (match_pos + cb->cur_boundary->len < len) {
+ if (rspamd_lc_cmp (pos, cb->cur_boundary->begin,
+ cb->cur_boundary->len) != 0) {
msg_debug_mime ("found invalid boundary: %*s, %T expected",
(gint)cb->cur_boundary->len, pos, cb->cur_boundary);
}
cb->part_start = pos;
+ cb->st->pos = pos;
}
else {
msg_debug_mime ("boundary is stripped");
+ g_set_error (cb->err, RSPAMD_MIME_QUARK, EINVAL,
+ "start boundary is stripped at %d (%zd available)",
+ match_pos, len);
+
return (-1);
}
}
else {
/* We see something like boundary: '[\r\n]--xxx */
/* TODO: write heuristic */
+ g_assert_not_reached ();
}
}
else {
/* We should have seen some boundary */
g_assert (cb->cur_boundary != NULL);
- if (match_pos + cb->cur_boundary->len > len) {
- if (memcmp (pos, cb->cur_boundary->begin, cb->cur_boundary->len) != 0) {
+ if (match_pos + cb->cur_boundary->len <= len) {
+ if (rspamd_lc_cmp (pos, cb->cur_boundary->begin,
+ cb->cur_boundary->len) != 0) {
msg_debug_mime ("found invalid boundary: %*s, %T expected",
(gint)cb->cur_boundary->len, pos, cb->cur_boundary);
}
pos += cb->cur_boundary->len;
+ cb->st->pos = pos;
if (pos < end - 1 && pos[0] == '-' && pos[1] == '-') {
/* It should be end of multipart, but it is sometimes isn't */
cb->st->stack->len - 1);
ret = 1;
}
-
- if (pos[0] != '\r' && pos[0] != '\n' && pos != end) {
+ else if (pos[0] != '\r' && pos[0] != '\n' && pos != end) {
/* This is not actually our boundary, but somethig else */
return 0;
}
/* Go towards the next part */
cb->part_start = pos;
+ cb->st->pos = pos;
}
else {
msg_debug_mime ("boundary is stripped");
+ g_set_error (cb->err, RSPAMD_MIME_QUARK, EINVAL,
+ "middle boundary is stripped at %d (%zd available)",
+ match_pos, len);
+
return (-1);
}
}
g_ptr_array_add (task->parts, part);
+ st->pos = part->raw_data.begin;
cbdata.multipart = part;
cbdata.task = task;
cbdata.st = st;
if (hdr_pos > 0 && hdr_pos < str.len) {
- if (st->cur_part == NULL) {
+ if (part == NULL) {
task->raw_headers_content.begin = (gchar *) (str.str);
task->raw_headers_content.len = hdr_pos;
task->raw_headers_content.body_start = str.str + body_pos;
}
else {
/* Adjust part data */
+ part->raw_headers = g_hash_table_new_full (rspamd_strcase_hash,
+ rspamd_strcase_equal, NULL, rspamd_ptr_array_free_hard);
part->raw_headers_str = str.str;
- part->raw_headers_len = str.len;
+ part->raw_headers_len = hdr_pos;
part->raw_data.begin = p + body_pos;
part->raw_data.len -= body_pos;
- if (task->raw_headers_content.len > 0) {
- rspamd_mime_headers_process (task, task->raw_headers,
+ if (part->raw_headers_len > 0) {
+ rspamd_mime_headers_process (task, part->raw_headers,
part->raw_headers_str,
part->raw_headers_len,
TRUE);
}
- hdrs = rspamd_message_get_header_from_hash (st->cur_part->raw_headers,
+ hdrs = rspamd_message_get_header_from_hash (part->raw_headers,
task->task_pool,
"Content-Type", FALSE);
}
npart->parent_part = part;
npart->ct = sel;
- if (st->cur_part == NULL) {
+ if (part == NULL) {
npart->raw_headers = g_hash_table_ref (task->raw_headers);
}
else {
- npart->raw_headers = g_hash_table_ref (st->cur_part->raw_headers);
+ npart->raw_headers = g_hash_table_ref (part->raw_headers);
}
if (sel->flags & RSPAMD_CONTENT_TYPE_MULTIPART) {