]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Implement glob maps in addition to regexp maps
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 23 Apr 2018 09:38:55 +0000 (10:38 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 23 Apr 2018 09:42:05 +0000 (10:42 +0100)
src/libutil/map.c
src/libutil/map.h
src/lua/lua_map.c

index aeb7f9ed36a59b83ca642ab62a88e3f8a115e6dd..bb9294553004693d8f883558e6f6ad8d1d348742 100644 (file)
@@ -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,
index b1479a1b1121f118cb8b26b2a3d35d22f9321248..0523c2a204ab13f5a704da48aebc61e904947ff6 100644 (file)
@@ -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);
 
 /**
index e01c1308d43c2d4bf73a38ab69c4174d63121aa1..7325dbf0ecda48fc96e6a112d1f6170cc474d30b 100644 (file)
@@ -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);