diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2021-07-16 12:24:29 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2021-07-16 12:24:29 +0100 |
commit | 8c9abcc404977124f44058c7738546f7ea2fc500 (patch) | |
tree | 1da8f42b0abc7b0c0a7437e3a17a9b6809714423 /src/libserver/composites | |
parent | 31fb7659830c79a2d252c67201cac5c19e132e56 (diff) | |
download | rspamd-8c9abcc404977124f44058c7738546f7ea2fc500.tar.gz rspamd-8c9abcc404977124f44058c7738546f7ea2fc500.zip |
[Fix] Fix storing of the regexps inside variant
Diffstat (limited to 'src/libserver/composites')
-rw-r--r-- | src/libserver/composites/composites.cxx | 52 |
1 files changed, 38 insertions, 14 deletions
diff --git a/src/libserver/composites/composites.cxx b/src/libserver/composites/composites.cxx index 17e8d7575..7778f854a 100644 --- a/src/libserver/composites/composites.cxx +++ b/src/libserver/composites/composites.cxx @@ -93,33 +93,56 @@ struct composites_data { }; struct rspamd_composite_option_match { - std::variant<rspamd_regexp_t *, std::string_view> match; + struct rspamd_regexp_wrapper { + explicit rspamd_regexp_wrapper(rspamd_regexp_t *re) noexcept : re(rspamd_regexp_ref(re)) {} + ~rspamd_regexp_wrapper() { + if (re) { + rspamd_regexp_unref(re); + } + } + rspamd_regexp_wrapper(const rspamd_regexp_wrapper &other) { + re = rspamd_regexp_ref(other.re); + } + rspamd_regexp_wrapper(rspamd_regexp_wrapper &&other) { + std::swap(re, other.re); + } + const rspamd_regexp_wrapper & operator= (const rspamd_regexp_wrapper &other) noexcept { + if (re) { + rspamd_regexp_unref(re); + } + re = rspamd_regexp_ref(other.re); + return *this; + } + const rspamd_regexp_wrapper & operator= (rspamd_regexp_wrapper &&other) noexcept { + std::swap(re, other.re); + return *this; + } + rspamd_regexp_wrapper() = default; + rspamd_regexp_t *re = nullptr; + }; + + std::variant<rspamd_regexp_wrapper, std::string_view> match; - explicit rspamd_composite_option_match(const char *start, std::size_t len) + explicit rspamd_composite_option_match(const char *start, std::size_t len) noexcept { match = std::string_view{start, len}; } - explicit rspamd_composite_option_match(rspamd_regexp_t *re) + explicit rspamd_composite_option_match(rspamd_regexp_t *re) noexcept { - match = re; + match = rspamd_regexp_wrapper(re); } - ~rspamd_composite_option_match() - { - if (std::holds_alternative<rspamd_regexp_t *>(match)) { - rspamd_regexp_unref(std::get<rspamd_regexp_t *>(match)); - } - } + ~rspamd_composite_option_match() = default; - auto math_opt(const std::string_view &data) const -> bool + auto match_opt(const std::string_view &data) const -> bool { return std::visit([&](auto arg) -> bool { if constexpr (std::is_same_v<decltype(arg), std::string_view>) { return data == arg; } else { - return rspamd_regexp_search(arg, + return rspamd_regexp_search(arg.re, data.data(), data.size(), nullptr, nullptr, false, nullptr); } @@ -133,7 +156,7 @@ struct rspamd_composite_option_match { return std::string_view(arg); } else { - return std::string_view(rspamd_regexp_get_pattern(arg)); + return std::string_view(rspamd_regexp_get_pattern(arg.re)); } }, match); } @@ -381,6 +404,7 @@ rspamd_composite_expr_parse(const gchar *line, gsize len, } else { atom->opts.emplace_back(re); + rspamd_regexp_unref(re); } if (*p == ',') { @@ -573,7 +597,7 @@ process_single_symbol(struct composites_data *cd, auto found = false; DL_FOREACH (ms->opts_head, opt) { - if (cur_opt.math_opt({opt->option, opt->optlen})) { + if (cur_opt.match_opt({opt->option, opt->optlen})) { found = true; break; } |