aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2018-04-23 10:38:55 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2018-04-23 10:42:05 +0100
commit12383cf84693cf54874ce8a33f0e1d26d1a6b1a4 (patch)
tree3997feaeb606f969bfe5f2d0655328637e0d73f1 /src
parent79f15b27c647f6a7028b6167f9c243ca3f6fa96a (diff)
downloadrspamd-12383cf84693cf54874ce8a33f0e1d26d1a6b1a4.tar.gz
rspamd-12383cf84693cf54874ce8a33f0e1d26d1a6b1a4.zip
[Feature] Implement glob maps in addition to regexp maps
Diffstat (limited to 'src')
-rw-r--r--src/libutil/map.c65
-rw-r--r--src/libutil/map.h5
-rw-r--r--src/lua/lua_map.c15
3 files changed, 85 insertions, 0 deletions
diff --git a/src/libutil/map.c b/src/libutil/map.c
index aeb7f9ed3..bb9294553 100644
--- a/src/libutil/map.c
+++ b/src/libutil/map.c
@@ -2825,6 +2825,48 @@ rspamd_re_map_insert_helper (gpointer st, gconstpointer key, gconstpointer value
}
static void
+rspamd_glob_map_insert_helper (gpointer st, gconstpointer key, gconstpointer value)
+{
+ struct rspamd_regexp_map *re_map = st;
+ struct rspamd_map *map;
+ rspamd_regexp_t *re;
+ gchar *escaped;
+ GError *err = NULL;
+ gint pcre_flags;
+ gsize escaped_len;
+
+ map = re_map->map;
+ escaped = rspamd_str_regexp_escape (key, strlen (key), &escaped_len, TRUE);
+ re = rspamd_regexp_new (escaped, NULL, &err);
+ g_free (escaped);
+
+ if (re == NULL) {
+ msg_err_map ("cannot parse regexp %s: %e", key, err);
+
+ if (err) {
+ g_error_free (err);
+ }
+
+ return;
+ }
+
+ pcre_flags = rspamd_regexp_get_pcre_flags (re);
+
+#ifndef WITH_PCRE2
+ if (pcre_flags & PCRE_FLAG(UTF8)) {
+ re_map->map_flags |= RSPAMD_REGEXP_FLAG_UTF;
+ }
+#else
+ if (pcre_flags & PCRE_FLAG(UTF)) {
+ re_map->map_flags |= RSPAMD_REGEXP_FLAG_UTF;
+ }
+#endif
+
+ g_ptr_array_add (re_map->regexps, re);
+ g_ptr_array_add (re_map->values, g_strdup (value));
+}
+
+static void
rspamd_re_map_finalize (struct rspamd_regexp_map *re_map)
{
#ifdef WITH_HYPERSCAN
@@ -2939,6 +2981,29 @@ rspamd_regexp_list_read_single (
}
gchar *
+rspamd_glob_list_read_single (
+ gchar *chunk,
+ gint len,
+ struct map_cb_data *data,
+ gboolean final)
+{
+ struct rspamd_regexp_map *re_map;
+
+ if (data->cur_data == NULL) {
+ re_map = rspamd_regexp_map_create (data->map, 0);
+ data->cur_data = re_map;
+ }
+
+ return rspamd_parse_kv_list (
+ chunk,
+ len,
+ data,
+ rspamd_glob_map_insert_helper,
+ hash_fill,
+ final);
+}
+
+gchar *
rspamd_regexp_list_read_multiple (
gchar *chunk,
gint len,
diff --git a/src/libutil/map.h b/src/libutil/map.h
index b1479a1b1..0523c2a20 100644
--- a/src/libutil/map.h
+++ b/src/libutil/map.h
@@ -129,6 +129,11 @@ gchar * rspamd_regexp_list_read_multiple (
gint len,
struct map_cb_data *data,
gboolean final);
+gchar * rspamd_glob_list_read_single (
+ gchar *chunk,
+ gint len,
+ struct map_cb_data *data,
+ gboolean final);
void rspamd_regexp_list_fin (struct map_cb_data *data);
/**
diff --git a/src/lua/lua_map.c b/src/lua/lua_map.c
index e01c1308d..7325dbf0e 100644
--- a/src/lua/lua_map.c
+++ b/src/lua/lua_map.c
@@ -547,6 +547,21 @@ lua_config_add_map (lua_State *L)
return 1;
}
}
+ else if (strcmp (type, "glob") == 0) {
+ map = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (*map));
+ map->data.re_map = NULL;
+ map->type = RSPAMD_LUA_MAP_REGEXP;
+
+ if ((m = rspamd_map_add_from_ucl (cfg, map_obj, description,
+ rspamd_glob_list_read_single,
+ rspamd_regexp_list_fin,
+ (void **) &map->data.re_map)) == NULL) {
+ lua_pushnil (L);
+ ucl_object_unref (map_obj);
+
+ return 1;
+ }
+ }
else {
ret = luaL_error (L, "invalid arguments: unknown type '%s'", type);
ucl_object_unref (map_obj);