gchar *header; /**< header name for header regexps */
gboolean is_test; /**< true if this expression must be tested */
gboolean is_strong; /**< true if headers search must be case sensitive */
+ gboolean is_multiple; /**< true if we need to match all inclusions of atom */
};
/**
result->is_strong = TRUE;
p++;
break;
+ case 'A':
+ result->is_multiple = TRUE;
+ p++;
+ break;
/* Stop flags parsing */
default:
p = NULL;
break;
case bad_atom:
g_set_error (err, rspamd_mime_expr_quark(), 100, "cannot parse"
- " mime atom '%*.s' when reading symbol '%c'", len, line, t);
+ " mime atom '%*.s' when reading symbol '%c'", (gint)len, line, t);
return NULL;
case end_atom:
goto set;
a->priority = 0;
a->data = mime_atom;
+ return a;
+
err:
if (mime_atom != NULL) {
g_free (mime_atom->str);
g_slice_free1 (sizeof (*mime_atom), mime_atom);
}
+
+ return NULL;
+}
+
+static gint
+rspamd_mime_regexp_element_process (struct rspamd_task *task,
+ struct rspamd_regexp_atom *re, const gchar *data, gsize len,
+ gboolean raw)
+{
+ guint r = 0;
+ const gchar *start = NULL, *end = NULL;
+
+ if ((r = rspamd_task_re_cache_check (task, re->regexp_text)) !=
+ RSPAMD_TASK_CACHE_NO_VALUE) {
+ debug_task ("regexp /%s/ is found in cache, result: %d",
+ re->regexp_text, r);
+ return r;
+ }
+
+ if (len == 0) {
+ len = strlen (data);
+ }
+
+ if (max_re_data != 0 && len > max_re_data) {
+ msg_info ("<%s> skip data of size %Hud",
+ task->message_id,
+ len);
+
+ return 0;
+ }
+
+ while (rspamd_regexp_search (re->regexp, data, len, &start, &end, raw)) {
+ if (G_UNLIKELY (re->is_test)) {
+ msg_info (
+ "process test regexp %s for header %s with value '%s' returned TRUE",
+ re->regexp_text,
+ re->header,
+ data);
+ }
+ r++;
+
+ if (!re->is_multiple) {
+ break;
+ }
+ }
+
+ if (r > 0) {
+ rspamd_task_re_cache_add (task, re->regexp_text, r);
+ }
+
+ return r;
}
struct url_regexp_param {
struct url_regexp_param *param = data;
struct rspamd_url *url = value;
- if (rspamd_regexp_search (param->regexp, struri (url), 0, NULL, NULL, FALSE)
- == TRUE) {
- if (G_UNLIKELY (param->re->is_test)) {
- msg_info ("process test regexp %s for url %s returned TRUE",
- struri (url));
- }
- task_cache_add (param->task, param->re, 1);
+ if (rspamd_mime_regexp_element_process (param->task, param->re,
+ struri (url), 0, FALSE)) {
param->found = TRUE;
return TRUE;
}
return FALSE;
}
-static gint
-rspamd_mime_regexp_element_process (struct rspamd_task *task,
- struct rspamd_regexp_atom *re, const guchar data, gsize len)
-{
- gint r;
- if ((r = task_cache_check (task, re)) != -1) {
- debug_task ("regexp /%s/ is found in cache, result: %d",
- re->regexp_text,
- r);
- return r == 1;
- }
-}
-
static gint
rspamd_mime_expr_process_regexp (struct rspamd_regexp_atom *re,
struct rspamd_task *task)
{
guint8 *ct;
gsize clen;
- gint r, passed = 0;
- gboolean matched = FALSE, raw = FALSE;
- const gchar *in, *start, *end;
+ gboolean raw = FALSE;
+ const gchar *in;
GList *cur, *headerlist;
rspamd_regexp_t *regexp;
if (re->header == NULL) {
msg_info ("header regexp without header name: '%s'",
re->regexp_text);
- task_cache_add (task, re, 0);
+ rspamd_task_re_cache_add (task, re->regexp_text, 0);
return 0;
}
debug_task ("checking %s header regexp: %s = %s",
re->regexp_text,
re->header);
}
- task_cache_add (task, re, 0);
+ rspamd_task_re_cache_add (task, re->regexp_text, 0);
return 0;
}
else {
if (re->regexp == NULL) {
debug_task ("regexp contains only header and it is found %s",
re->header);
- task_cache_add (task, re, 1);
+ rspamd_task_re_cache_add (task, re->regexp_text, 1);
return 1;
}
/* Iterate through headers */
}
/* Match re */
- if (in &&
- rspamd_regexp_search (regexp, in, 0, NULL, NULL, raw)) {
- if (G_UNLIKELY (re->is_test)) {
- msg_info (
- "process test regexp %s for header %s with value '%s' returned TRUE",
- re->regexp_text,
- re->header,
- in);
- }
- task_cache_add (task, re, 1);
+ if (in && rspamd_mime_regexp_element_process (task, re, in,
+ strlen (in), raw)) {
+
return 1;
}
- else if (G_UNLIKELY (re->is_test)) {
- msg_info (
- "process test regexp %s for header %s with value '%s' returned FALSE",
- re->regexp_text,
- re->header,
- in);
- }
+
cur = g_list_next (cur);
}
- task_cache_add (task, re, 0);
- return 0;
+
+ rspamd_task_re_cache_add (task, re->regexp_text, 0);
}
break;
case REGEXP_MIME:
cur = g_list_next (cur);
continue;
}
- /* Skip too large parts */
- if (max_re_data != 0 && part->content->len > max_re_data) {
- msg_info ("<%s> skip part of size %Hud",
- task->message_id,
- part->content->len);
- cur = g_list_next (cur);
- continue;
- }
-
- regexp = re->regexp;
/* Check raw flags */
if (part->is_raw) {
clen = part->content->len;
}
/* If we have limit, apply regexp so much times as we can */
- if (rspamd_regexp_search (regexp, ct, clen, NULL, NULL, raw)) {
- if (G_UNLIKELY (re->is_test)) {
- msg_info (
- "process test regexp %s for mime part of length %d returned TRUE",
- re->regexp_text,
- (gint)clen);
- }
- task_cache_add (task, re, 1);
+ if (rspamd_mime_regexp_element_process (task, re, ct, clen, raw)) {
return 1;
}
- if (!matched && G_UNLIKELY (re->is_test)) {
- msg_info (
- "process test regexp %s for mime part of length %d returned FALSE",
- re->regexp_text,
- (gint)clen);
- }
cur = g_list_next (cur);
}
- task_cache_add (task, re, 0);
+ rspamd_task_re_cache_add (task, re->regexp_text, 0);
break;
case REGEXP_MESSAGE:
debug_task ("checking message regexp: %s", re->regexp_text);
raw = TRUE;
- regexp = re->regexp;
ct = (guint8 *)task->msg.start;
clen = task->msg.len;
- if (max_re_data != 0 && clen > max_re_data) {
- msg_info ("<%s> skip message of size %Hz", task->message_id, clen);
- return 0;
- }
- if (rspamd_regexp_search (regexp, ct, clen, NULL, NULL, raw)) {
- if (G_UNLIKELY (re->is_test)) {
- msg_info (
- "process test regexp %s for message part of length %d returned TRUE",
- re->regexp_text,
- (gint)clen);
- }
- task_cache_add (task, re, 1);
+ if (rspamd_mime_regexp_element_process (task, re, ct, clen, raw)) {
return 1;
}
- if (!matched && G_UNLIKELY (re->is_test)) {
- msg_info (
- "process test regexp %s for message part of length %d returned FALSE",
- re->regexp_text,
- (gint)clen);
- }
- task_cache_add (task, re, 0);
+ rspamd_task_re_cache_add (task, re->regexp_text, 0);
break;
case REGEXP_URL:
debug_task ("checking url regexp: %s", re->regexp_text);
g_tree_foreach (task->emails, tree_url_callback, &callback_param);
}
if (callback_param.found == FALSE) {
- task_cache_add (task, re, 0);
+ rspamd_task_re_cache_add (task, re->regexp_text, 0);
}
break;
default:
break;
}
- /* Not reached */
return 0;
}