}
else {
while (remain > 0) {
- c = g_utf8_get_char (p);
+ c = g_utf8_get_char_validated (p, remain);
+ if (c == (gunichar)-2 || c == (gunichar)-1) {
+ /* Invalid characters detected, stop processing*/
+ return FALSE;
+ }
+
scc = g_unichar_get_script (c);
p1 = g_utf8_next_char (p);
remain -= p1 - p;
p = p1;
if (remain > 0) {
- t = g_utf8_get_char (p);
+ t = g_utf8_get_char_validated (p, remain);
+ if (c == (gunichar)-2 || c == (gunichar)-1) {
+ /* Invalid characters detected, stop processing*/
+ return FALSE;
+ }
sct = g_unichar_get_script (t);
if (g_unichar_isalnum (c) && g_unichar_isalnum (t)) {
/* We have two unicode alphanumeric characters, so we can check its script */
#include "../cfg_file.h"
#include "../expressions.h"
+#define DEFAULT_STATFILE_PREFIX "./"
+
struct regexp_module_item {
struct expression *expr;
char *symbol;
};
+struct autolearn_data {
+ char *statfile_name;
+ char *symbol;
+ float weight;
+};
+
struct regexp_ctx {
int (*header_filter)(struct worker_task *task);
int (*mime_filter)(struct worker_task *task);
int (*message_filter)(struct worker_task *task);
int (*url_filter)(struct worker_task *task);
GList *items;
+ GHashTable *autolearn_symbols;
char *metric;
+ char *statfile_prefix;
memory_pool_t *regexp_pool;
};
regexp_module_ctx->url_filter = NULL;
regexp_module_ctx->regexp_pool = memory_pool_new (1024);
regexp_module_ctx->items = NULL;
+ regexp_module_ctx->autolearn_symbols = g_hash_table_new (g_str_hash, g_str_equal);
*ctx = (struct module_ctx *)regexp_module_ctx;
register_expression_function ("regexp_match_number", rspamd_regexp_match_number);
return TRUE;
}
+/*
+ * Parse string in format:
+ * SYMBOL:statfile:weight
+ */
+void
+parse_autolearn_param (const char *param, const char *value, struct config_file *cfg)
+{
+ struct autolearn_data *d;
+ char *p;
+
+ p = memory_pool_strdup (regexp_module_ctx->regexp_pool, value);
+ d = memory_pool_alloc (regexp_module_ctx->regexp_pool, sizeof (struct autolearn_data));
+
+ d->symbol = strsep (&p, ":");
+ if (d->symbol) {
+ d->statfile_name = strsep (&p, ":");
+ if (d->statfile_name) {
+ if (p != NULL && *p != '\0') {
+ d->weight = strtod (p, NULL);
+ g_hash_table_insert (regexp_module_ctx->autolearn_symbols, d->symbol, d);
+ }
+ }
+ else {
+ msg_warn ("parse_autolearn_param: cannot extract statfile name from %s", p);
+ }
+ }
+ else {
+ msg_warn ("parse_autolearn_param: cannot extract symbol name from %s", p);
+ }
+}
+
int
regexp_module_config (struct config_file *cfg)
{
else {
regexp_module_ctx->metric = DEFAULT_METRIC;
}
+ if ((value = get_module_opt (cfg, "regexp", "statfile_prefix")) != NULL) {
+ regexp_module_ctx->statfile_prefix = memory_pool_strdup (regexp_module_ctx->regexp_pool, value);
+ g_free (value);
+ }
+ else {
+ regexp_module_ctx->metric = DEFAULT_STATFILE_PREFIX;
+ }
cur_module_opt = g_hash_table_lookup (cfg->modules_opts, "regexp");
if (cur_module_opt != NULL) {
LIST_FOREACH (cur, cur_module_opt, next) {
- if (strcmp (cur->param, "metric") == 0) {
+ if (strcmp (cur->param, "metric") == 0 || strcmp (cur->param, "statfile_prefix") == 0) {
+ continue;
+ }
+ else if (g_ascii_strncasecmp (cur->param, "autolearn", sizeof ("autolearn") - 1)) {
+ parse_autolearn_param (cur->param, cur->value, cfg);
continue;
}
cur_item = memory_pool_alloc0 (regexp_module_ctx->regexp_pool, sizeof (struct regexp_module_item));