From 12383cf84693cf54874ce8a33f0e1d26d1a6b1a4 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Mon, 23 Apr 2018 10:38:55 +0100 Subject: [PATCH] [Feature] Implement glob maps in addition to regexp maps --- src/libutil/map.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++ src/libutil/map.h | 5 ++++ src/lua/lua_map.c | 15 +++++++++++ 3 files changed, 85 insertions(+) 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 @@ -2824,6 +2824,48 @@ rspamd_re_map_insert_helper (gpointer st, gconstpointer key, gconstpointer value g_ptr_array_add (re_map->values, g_strdup (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) { @@ -2938,6 +2980,29 @@ rspamd_regexp_list_read_single ( final); } +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, 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); -- 2.39.5