void
rspamd_content_type_add_param (rspamd_mempool_t *pool,
struct rspamd_content_type *ct,
- const gchar *name_start, const gchar *name_end,
- const gchar *value_start, const gchar *value_end)
+ gchar *name_start, gchar *name_end,
+ gchar *value_start, gchar *value_end)
{
rspamd_ftok_t srch;
struct rspamd_content_type_param *found = NULL, *nparam;
g_assert (ct != NULL);
- srch.begin = name_start;
- srch.len = name_end - name_start;
-
- if (ct->attrs) {
- found = g_hash_table_lookup (ct->attrs, &srch);
- }
- else {
- ct->attrs = g_hash_table_new (rspamd_ftok_icase_hash,
- rspamd_ftok_icase_equal);
- }
nparam = rspamd_mempool_alloc (pool, sizeof (*nparam));
nparam->name.begin = name_start;
nparam->name.len = name_end - name_start;
+ rspamd_str_lc (name_start, name_end - name_start);
+
nparam->value.begin = value_start;
nparam->value.len = value_end - value_start;
- if (!found) {
- DL_APPEND (found, nparam);
- g_hash_table_insert (ct->attrs, &nparam->name, nparam);
- }
- else {
- DL_APPEND (found, nparam);
- }
-
RSPAMD_FTOK_ASSIGN (&srch, "charset");
if (rspamd_ftok_cmp (&nparam->name, &srch) == 0) {
/* Adjust charset */
+ found = nparam;
ct->charset.begin = nparam->value.begin;
ct->charset.len = nparam->value.len;
}
RSPAMD_FTOK_ASSIGN (&srch, "boundary");
if (rspamd_ftok_cmp (&nparam->name, &srch) == 0) {
+ found = nparam;
+ gchar *lc_boundary;
/* Adjust boundary */
- ct->boundary.begin = nparam->value.begin;
+ lc_boundary = rspamd_mempool_alloc (pool, nparam->value.len);
+ memcpy (lc_boundary, nparam->value.begin, nparam->value.len);
+ rspamd_str_lc (lc_boundary, nparam->value.len);
+ ct->boundary.begin = lc_boundary;
ct->boundary.len = nparam->value.len;
+ /* Preserve original (case sensitive) boundary */
+ ct->orig_boundary.begin = nparam->value.begin;
+ ct->orig_boundary.len = nparam->value.len;
+ }
+
+ if (!found) {
+ srch.begin = nparam->name.begin;
+ srch.len = nparam->name.len;
+
+ rspamd_str_lc (value_start, value_end - value_start);
+
+ if (ct->attrs) {
+ found = g_hash_table_lookup (ct->attrs, &srch);
+ } else {
+ ct->attrs = g_hash_table_new (rspamd_ftok_icase_hash,
+ rspamd_ftok_icase_equal);
+ }
+
+ if (!found) {
+ DL_APPEND (found, nparam);
+ g_hash_table_insert (ct->attrs, &nparam->name, nparam);
+ }
+ else {
+ DL_APPEND (found, nparam);
+ }
}
}
static struct rspamd_content_type *
-rspamd_content_type_parser (const gchar *in, gsize len, rspamd_mempool_t *pool)
+rspamd_content_type_parser (gchar *in, gsize len, rspamd_mempool_t *pool)
{
guint obraces = 0, ebraces = 0, qlen = 0;
- const gchar *p, *c, *end, *pname_start = NULL, *pname_end = NULL;
+ gchar *p, *c, *end, *pname_start = NULL, *pname_end = NULL;
struct rspamd_content_type *res = NULL, val;
gboolean eqsign_seen = FALSE;
enum {
c = p;
end = p + len;
memset (&val, 0, sizeof (val));
- val.lc_data = (gchar *)in;
+ val.cpy = in;
while (p < end) {
switch (state) {
if (val.type.len > 0) {
res = rspamd_mempool_alloc (pool, sizeof (val));
memcpy (res, &val, sizeof (val));
+
+ /* Lowercase common thingies */
+
}
return res;
rspamd_ftok_t srch;
gchar *lc_data;
- lc_data = rspamd_mempool_alloc (pool, len);
- memcpy (lc_data, in, len);
- rspamd_str_lc (lc_data, len);
+ lc_data = rspamd_mempool_alloc (pool, len + 1);
+ rspamd_strlcpy (lc_data, in, len + 1);
if ((res = rspamd_content_type_parser (lc_data, len, pool)) != NULL) {
if (res->attrs) {
};
struct rspamd_content_type {
- gchar *lc_data;
+ gchar *cpy;
rspamd_ftok_t type;
rspamd_ftok_t subtype;
rspamd_ftok_t charset;
rspamd_ftok_t boundary;
+ rspamd_ftok_t orig_boundary;
enum rspamd_content_type_flags flags;
GHashTable *attrs; /* Can be empty */
};
/**
* Adds new parameter to content type structure
* @param ct
- * @param name_start
+ * @param name_start (can be modified)
* @param name_end
- * @param value_start
+ * @param value_start (can be modified)
* @param value_end
*/
void
rspamd_content_type_add_param (rspamd_mempool_t *pool,
- struct rspamd_content_type *ct,
- const gchar *name_start, const gchar *name_end,
- const gchar *value_start, const gchar *value_end);
+ struct rspamd_content_type *ct,
+ gchar *name_start, gchar *name_end,
+ gchar *value_start, gchar *value_end);
/**
* Parse content type from the header (performs copy + lowercase)
npart->headers_order = g_queue_new ();
if (multipart) {
- if (multipart->specific.mp.children == NULL) {
- multipart->specific.mp.children = g_ptr_array_sized_new (2);
+ 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);
+ g_ptr_array_add (multipart->specific.mp->children, npart);
}
if (hdr_pos > 0 && hdr_pos < str.len) {
if (sel->flags & RSPAMD_CONTENT_TYPE_MULTIPART) {
st->nesting ++;
g_ptr_array_add (st->stack, npart);
+ npart->specific.mp = rspamd_mempool_alloc0 (task->task_pool,
+ sizeof (struct rspamd_mime_multipart));
+ memcpy (&npart->specific.mp->boundary, &sel->orig_boundary,
+ sizeof (rspamd_ftok_t));
ret = rspamd_mime_parse_multipart_part (task, npart, st, err);
}
else if (sel->flags & RSPAMD_CONTENT_TYPE_MESSAGE) {
if (sel->flags & RSPAMD_CONTENT_TYPE_MULTIPART) {
g_ptr_array_add (nst->stack, npart);
nst->nesting ++;
+ npart->specific.mp = rspamd_mempool_alloc0 (task->task_pool,
+ sizeof (struct rspamd_mime_multipart));
+ memcpy (&npart->specific.mp->boundary, &sel->orig_boundary,
+ sizeof (rspamd_ftok_t));
ret = rspamd_mime_parse_multipart_part (task, npart, nst, err);
}
else if (sel->flags & RSPAMD_CONTENT_TYPE_MESSAGE) {