static guint rspamd_re_cache_process_regexp_data (struct rspamd_re_runtime *rt, rspamd_regexp_t *re, rspamd_mempool_t *pool, const guchar **in, guint *lens, guint count, gboolean is_raw) { guint64 re_id; guint ret = 0; guint i; re_id = rspamd_regexp_get_cache_id (re); if (count == 0 || in == NULL) { /* We assume this as absence of the specified data */ setbit (rt->checked, re_id); rt->results[re_id] = ret; return ret; } #ifndef WITH_HYPERSCAN for (i = 0; i < count; i++) { ret = rspamd_re_cache_process_pcre (rt, re, pool, in[i], lens[i], is_raw); } setbit (rt->checked, re_id); rt->results[re_id] = ret; #else struct rspamd_re_cache_elt *elt; struct rspamd_re_class *re_class; struct rspamd_re_hyperscan_cbdata cbdata; elt = g_ptr_array_index (rt->cache->re, re_id); re_class = rspamd_regexp_get_class (re); if (rt->cache->disable_hyperscan || elt->match_type == RSPAMD_RE_CACHE_PCRE) { for (i = 0; i < count; i++) { ret = rspamd_re_cache_process_pcre (rt, re, pool, in[i], lens[i], is_raw); } setbit (rt->checked, re_id); rt->results[re_id] = ret; } else { for (i = 0; i < count; i ++) { if (rt->cache->max_re_data > 0 && lens[i] > rt->cache->max_re_data) { lens[i] = rt->cache->max_re_data; } rt->stat.bytes_scanned += lens[i]; } g_assert (re_class->hs_scratch != NULL); g_assert (re_class->hs_db != NULL); /* Go through hyperscan API */ if (!rt->cache->vectorized_hyperscan) { for (i = 0; i < count; i++) { cbdata.ins = &in[i]; cbdata.re = re; cbdata.rt = rt; cbdata.lens = &lens[i]; cbdata.count = 1; cbdata.pool = pool; if ((hs_scan (re_class->hs_db, in[i], lens[i], 0, re_class->hs_scratch, rspamd_re_cache_hyperscan_cb, &cbdata)) != HS_SUCCESS) { ret = 0; } else { ret = rt->results[re_id]; } } } else { cbdata.ins = in; cbdata.re = re; cbdata.rt = rt; cbdata.lens = lens; cbdata.count = 1; cbdata.pool = pool; if ((hs_scan_vector (re_class->hs_db, (const char **)in, lens, count, 0, re_class->hs_scratch, rspamd_re_cache_hyperscan_cb, &cbdata)) != HS_SUCCESS) { ret = 0; } else { ret = rt->results[re_id]; } } } #endif return ret; }
static guint rspamd_re_cache_process_regexp_data (struct rspamd_re_runtime *rt, rspamd_regexp_t *re, rspamd_mempool_t *pool, const guchar *in, gsize len, gboolean is_raw) { guint64 re_id; guint ret = 0; re_id = rspamd_regexp_get_cache_id (re); if (len == 0 || in == NULL) { /* We assume this as absence of the specified data */ setbit (rt->checked, re_id); rt->results[re_id] = ret; return ret; } #ifndef WITH_HYPERSCAN ret = rspamd_re_cache_process_pcre (rt, re, pool, in, len, is_raw); setbit (rt->checked, re_id); rt->results[re_id] = ret; #else struct rspamd_re_cache_elt *elt; struct rspamd_re_class *re_class; struct rspamd_re_hyperscan_cbdata cbdata; elt = g_ptr_array_index (rt->cache->re, re_id); re_class = rspamd_regexp_get_class (re); if (rt->cache->disable_hyperscan || elt->match_type == RSPAMD_RE_CACHE_PCRE) { ret = rspamd_re_cache_process_pcre (rt, re, pool, in, len, is_raw); setbit (rt->checked, re_id); rt->results[re_id] = ret; } else { if (rt->cache->max_re_data > 0 && len > rt->cache->max_re_data) { len = rt->cache->max_re_data; } g_assert (re_class->hs_scratch != NULL); g_assert (re_class->hs_db != NULL); /* Go through hyperscan API */ cbdata.in = in; cbdata.re = re; cbdata.rt = rt; cbdata.len = len; cbdata.pool = pool; rt->stat.bytes_scanned += len; if ((hs_scan (re_class->hs_db, in, len, 0, re_class->hs_scratch, rspamd_re_cache_hyperscan_cb, &cbdata)) != HS_SUCCESS) { ret = 0; } else { ret = rt->results[re_id]; } } #endif return ret; }