#include <cmath>
#include <vector>
#include <variant>
+#include "libutil/cxx/util.hxx"
#include "contrib/robin-hood/robin_hood.h"
#include "composites_internal.hxx"
struct rspamd_composite_atom {
std::string symbol;
+ std::string_view norm_symbol;
rspamd_composite_atom_type comp_type = rspamd_composite_atom_type::ATOM_UNKNOWN;
const struct rspamd_composite *ncomp; /* underlying composite */
std::vector<rspamd_composite_option_match> opts;
}
switch (state) {
- case comp_state_read_symbol:
+ case comp_state_read_symbol: {
clen = rspamd_memcspn(p, "[; \t()><!|&\n", len);
p += clen;
}
atom->symbol = std::string{line, clen};
+ auto norm_start = std::find_if(atom->symbol.begin(), atom->symbol.end(),
+ [](char c) { return g_ascii_isalnum(c); });
+ if (norm_start == atom->symbol.end()) {
+ msg_err_pool("invalid composite atom: %s", atom->symbol.c_str());
+ }
+ atom->norm_symbol = make_string_view_from_it(norm_start, atom->symbol.end());
break;
+ }
case comp_state_read_obrace:
p++;
if (ms) {
if (ms->score == 0) {
- rc = 0.001; /* Distinguish from 0 */
+ rc = epsilon * 16.0; /* Distinguish from 0 */
}
else {
rc = ms->score;
if (cd->checked[cd->composite->id * 2]) {
/* We have already checked this composite, so just return its value */
if (cd->checked[cd->composite->id * 2 + 1]) {
- ms = rspamd_task_find_symbol_result(cd->task, comp_atom->symbol.c_str(),
+ ms = rspamd_task_find_symbol_result(cd->task,
+ comp_atom->norm_symbol.data(),
cd->metric_res);
}
}
/* Note: sym is zero terminated as it is a view on std::string */
- auto sym = std::string_view{comp_atom->symbol};
+ auto sym = comp_atom->norm_symbol;
auto group_process_functor = [&](auto cond, int sub_start) -> double {
auto max = 0.;
GHashTableIter it;
}
}
- msg_debug_composites ("%s: final result for composite %s is %.2f",
+ msg_debug_composites ("%s: final result for composite %s is %.4f",
cd->metric_res->name,
cd->composite->sym.c_str(), rc);