From: Vsevolod Stakhov Date: Tue, 15 Jul 2025 10:09:45 +0000 (+0100) Subject: [Feature] Allow to pass expression flags in the regexp plugin X-Git-Tag: 3.13.0~46^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9d00f09a5850ef98e713eaf4465ba93ad8c7cbf0;p=thirdparty%2Frspamd.git [Feature] Allow to pass expression flags in the regexp plugin --- diff --git a/src/plugins/regexp.c b/src/plugins/regexp.c index 414e1b3a63..85beccd93d 100644 --- a/src/plugins/regexp.c +++ b/src/plugins/regexp.c @@ -32,6 +32,7 @@ struct regexp_module_item { struct rspamd_expression *expr; const char *symbol; struct ucl_lua_funcdata *lua_function; + int expression_flags; }; struct regexp_ctx { @@ -68,12 +69,53 @@ regexp_get_context(struct rspamd_config *cfg) } /* Process regexp expression */ +static int +parse_expression_flags(const ucl_object_t *flags_obj) +{ + int flags = 0; + const ucl_object_t *cur; + ucl_object_iter_t it = NULL; + const char *flag_name; + + if (!flags_obj) { + return 0; + } + + if (ucl_object_type(flags_obj) == UCL_ARRAY) { + /* Array of flag names */ + while ((cur = ucl_object_iterate(flags_obj, &it, true)) != NULL) { + if (ucl_object_type(cur) == UCL_STRING) { + flag_name = ucl_object_tostring(cur); + if (strcmp(flag_name, "noopt") == 0) { + flags |= RSPAMD_EXPRESSION_FLAG_NOOPT; + } + else { + msg_warn("unknown expression flag: %s", flag_name); + } + } + } + } + else if (ucl_object_type(flags_obj) == UCL_STRING) { + /* Single flag name */ + flag_name = ucl_object_tostring(flags_obj); + if (strcmp(flag_name, "noopt") == 0) { + flags |= RSPAMD_EXPRESSION_FLAG_NOOPT; + } + else { + msg_warn("unknown expression flag: %s", flag_name); + } + } + + return flags; +} + static gboolean read_regexp_expression(rspamd_mempool_t *pool, struct regexp_module_item *chain, const char *symbol, const char *line, - struct rspamd_mime_expr_ud *ud) + struct rspamd_mime_expr_ud *ud, + int expression_flags) { struct rspamd_expression *e = NULL; GError *err = NULL; @@ -90,6 +132,7 @@ read_regexp_expression(rspamd_mempool_t *pool, g_assert(e != NULL); chain->expr = e; + chain->expression_flags = expression_flags; return TRUE; } @@ -165,13 +208,14 @@ int regexp_module_config(struct rspamd_config *cfg, bool validate) sizeof(struct regexp_module_item)); cur_item->symbol = ucl_object_key(value); cur_item->magic = rspamd_regexp_cb_magic; + cur_item->expression_flags = 0; ud.conf_obj = NULL; ud.cfg = cfg; if (!read_regexp_expression(cfg->cfg_pool, cur_item, ucl_object_key(value), - ucl_obj_tostring(value), &ud)) { + ucl_obj_tostring(value), &ud, 0)) { if (validate) { return FALSE; } @@ -193,6 +237,7 @@ int regexp_module_config(struct rspamd_config *cfg, bool validate) cur_item->magic = rspamd_regexp_cb_magic; cur_item->symbol = ucl_object_key(value); cur_item->lua_function = ucl_object_toclosure(value); + cur_item->expression_flags = 0; rspamd_symcache_add_symbol(cfg->cache, cur_item->symbol, @@ -225,9 +270,13 @@ int regexp_module_config(struct rspamd_config *cfg, bool validate) ud.cfg = cfg; ud.conf_obj = value; + /* Look for expression_flags */ + const ucl_object_t *flags_obj = ucl_object_lookup(value, "expression_flags"); + int expr_flags = parse_expression_flags(flags_obj); + if (!read_regexp_expression(cfg->cfg_pool, cur_item, ucl_object_key(value), - ucl_obj_tostring(elt), &ud)) { + ucl_obj_tostring(elt), &ud, expr_flags)) { if (validate) { return FALSE; } @@ -253,6 +302,7 @@ int regexp_module_config(struct rspamd_config *cfg, bool validate) cur_item->magic = rspamd_regexp_cb_magic; cur_item->symbol = ucl_object_key(value); cur_item->lua_function = ucl_object_toclosure(value); + cur_item->expression_flags = 0; } if (cur_item && (is_lua || valid_expression)) { @@ -548,7 +598,7 @@ process_regexp_item(struct rspamd_task *task, else { /* Process expression */ if (item->expr) { - res = rspamd_process_expression(item->expr, 0, task); + res = rspamd_process_expression(item->expr, item->expression_flags, task); } else { msg_warn_task("FIXME: %s symbol is broken with new expressions",