aboutsummaryrefslogtreecommitdiffstats
path: root/src/libutil/map.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-03-16 17:50:14 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-03-16 17:50:14 +0000
commit0dca31d70718c5bbefc5013052f94115084fc548 (patch)
tree11e6df8cdc76b38b5c8e81bccf04d6e5752c38e2 /src/libutil/map.c
parent4ce6722cedb43293ee58e96b84c40dd9ed4b7a9c (diff)
downloadrspamd-0dca31d70718c5bbefc5013052f94115084fc548.tar.gz
rspamd-0dca31d70718c5bbefc5013052f94115084fc548.zip
[Feature] Add method to check regexp maps
Diffstat (limited to 'src/libutil/map.c')
-rw-r--r--src/libutil/map.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/libutil/map.c b/src/libutil/map.c
index b1ebc1e4c..ffb426ea0 100644
--- a/src/libutil/map.c
+++ b/src/libutil/map.c
@@ -1646,3 +1646,58 @@ rspamd_regexp_list_fin (rspamd_mempool_t *pool, struct map_cb_data *data)
re_map->regexps->len);
}
}
+
+static int
+rspamd_match_hs_single_handler (unsigned int id, unsigned long long from,
+ unsigned long long to,
+ unsigned int flags, void *context)
+{
+ guint *i = context;
+ /* Always return non-zero as we need a single match here */
+
+ *i = id;
+
+ return 1;
+}
+
+gpointer
+rspamd_match_regexp_map (struct rspamd_regexp_map *map,
+ const gchar *in, gsize len)
+{
+ guint i;
+ rspamd_regexp_t *re;
+ gint res = 0;
+ gpointer ret = NULL;
+
+ g_assert (in != NULL && len > 0);
+
+ if (map == NULL) {
+ return NULL;
+ }
+
+#ifdef WITH_HYPERSCAN
+ if (map->hs_db && map->hs_scratch) {
+ res = hs_scan (map->hs_db, in, len, 0, map->hs_scratch,
+ rspamd_match_hs_single_handler, (void *)&i);
+
+ if (res == HS_SCAN_TERMINATED) {
+ res = 1;
+ ret = g_ptr_array_index (map->values, i);
+ }
+ }
+#endif
+
+ if (!res) {
+ /* PCRE version */
+ for (i = 0; i < map->regexps->len; i ++) {
+ re = g_ptr_array_index (map->regexps, i);
+
+ if (rspamd_regexp_search (re, in, len, NULL, NULL, FALSE, NULL)) {
+ ret = g_ptr_array_index (map->values, i);
+ break;
+ }
+ }
+ }
+
+ return ret;
+}