From: Vsevolod Stakhov Date: Tue, 9 Oct 2018 11:37:02 +0000 (+0100) Subject: [Feature] Allow `g+:` and `g-:` composite atoms X-Git-Tag: 1.8.1~57 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a532a2ddf2797a6c3156edc42310e5708363eefb;p=thirdparty%2Frspamd.git [Feature] Allow `g+:` and `g-:` composite atoms --- diff --git a/src/libserver/composites.c b/src/libserver/composites.c index 83f3a35d49..d553ce7efe 100644 --- a/src/libserver/composites.c +++ b/src/libserver/composites.c @@ -94,7 +94,7 @@ rspamd_composite_expr_parse (const gchar *line, gsize len, /* * Composites are just sequences of symbols */ - clen = strcspn (line, ", \t()><+!|&\n"); + clen = strcspn (line, ", \t()>symbols_to_remove, ms->name); + + nrd = rspamd_mempool_alloc (cd->task->task_pool, sizeof (*nrd)); + nrd->sym = ms->name; + + /* By default remove symbols */ + switch (cd->composite->policy) { + case RSPAMD_COMPOSITE_POLICY_REMOVE_ALL: + default: + nrd->action = (RSPAMD_COMPOSITE_REMOVE_SYMBOL|RSPAMD_COMPOSITE_REMOVE_WEIGHT); + break; + case RSPAMD_COMPOSITE_POLICY_REMOVE_SYMBOL: + nrd->action = RSPAMD_COMPOSITE_REMOVE_SYMBOL; + break; + case RSPAMD_COMPOSITE_POLICY_REMOVE_WEIGHT: + nrd->action = RSPAMD_COMPOSITE_REMOVE_WEIGHT; + break; + case RSPAMD_COMPOSITE_POLICY_LEAVE: + nrd->action = 0; + break; + } + + for (;;) { + t = *beg; + + if (t == '~') { + nrd->action &= ~RSPAMD_COMPOSITE_REMOVE_SYMBOL; + } + else if (t == '-') { + nrd->action &= ~(RSPAMD_COMPOSITE_REMOVE_WEIGHT| + RSPAMD_COMPOSITE_REMOVE_SYMBOL); + } + else if (t == '^') { + nrd->action |= RSPAMD_COMPOSITE_REMOVE_FORCED; + } + else { + break; + } + + beg ++; + } + + nrd->comp = cd->composite; + nrd->parent = atom->parent; + + if (rd == NULL) { + DL_APPEND (rd, nrd); + g_hash_table_insert (cd->symbols_to_remove, (gpointer)ms->name, rd); + } + else { + DL_APPEND (rd, nrd); + } +} + static gdouble -rspamd_composite_expr_process (struct rspamd_expr_process_data *process_data, rspamd_expression_atom_t *atom) +rspamd_composite_expr_process (struct rspamd_expr_process_data *process_data, + rspamd_expression_atom_t *atom) { struct composites_data *cd = process_data->cd; const gchar *beg = atom->data, *sym = NULL; - gchar t; - struct symbol_remove_data *rd, *nrd; + struct rspamd_symbol_result *ms = NULL; struct rspamd_symbols_group *gr; struct rspamd_symbol *sdef; @@ -225,73 +298,70 @@ rspamd_composite_expr_process (struct rspamd_expr_process_data *process_data, rs rc = rspamd_composite_process_single_symbol (cd, sdef->name, &ms); if (rc) { - break; + rspamd_composite_process_symbol_removal (atom, + cd, + ms, + beg); } } } } - else { - rc = rspamd_composite_process_single_symbol (cd, sym, &ms); - } + else if (strncmp (sym, "g+:", 3) == 0) { + /* Group, positive symbols only */ + gr = g_hash_table_lookup (cd->task->cfg->groups, sym + 3); - if (rc != 0 && ms) { - /* - * At this point we know that we need to do something about this symbol, - * however, we don't know whether we need to delete it unfortunately, - * that depends on the later decisions when the complete expression is - * evaluated. - */ - rd = g_hash_table_lookup (cd->symbols_to_remove, ms->name); + if (gr != NULL) { + g_hash_table_iter_init (&it, gr->symbols); - nrd = rspamd_mempool_alloc (cd->task->task_pool, sizeof (*nrd)); - nrd->sym = ms->name; + while (g_hash_table_iter_next (&it, &k, &v)) { + sdef = v; - /* By default remove symbols */ - switch (cd->composite->policy) { - case RSPAMD_COMPOSITE_POLICY_REMOVE_ALL: - default: - nrd->action = (RSPAMD_COMPOSITE_REMOVE_SYMBOL|RSPAMD_COMPOSITE_REMOVE_WEIGHT); - break; - case RSPAMD_COMPOSITE_POLICY_REMOVE_SYMBOL: - nrd->action = RSPAMD_COMPOSITE_REMOVE_SYMBOL; - break; - case RSPAMD_COMPOSITE_POLICY_REMOVE_WEIGHT: - nrd->action = RSPAMD_COMPOSITE_REMOVE_WEIGHT; - break; - case RSPAMD_COMPOSITE_POLICY_LEAVE: - nrd->action = 0; - break; + if (sdef->score > 0) { + rc = rspamd_composite_process_single_symbol (cd, + sdef->name, + &ms); + + if (rc) { + rspamd_composite_process_symbol_removal (atom, + cd, + ms, + beg); + } + } + } } + } + else if (strncmp (sym, "g-:", 3) == 0) { + /* Group, positive symbols only */ + gr = g_hash_table_lookup (cd->task->cfg->groups, sym + 3); - for (;;) { - t = *beg; - - if (t == '~') { - nrd->action &= ~RSPAMD_COMPOSITE_REMOVE_SYMBOL; - } - else if (t == '-') { - nrd->action &= ~(RSPAMD_COMPOSITE_REMOVE_WEIGHT| - RSPAMD_COMPOSITE_REMOVE_SYMBOL); - } - else if (t == '^') { - nrd->action |= RSPAMD_COMPOSITE_REMOVE_FORCED; - } - else { - break; - } + if (gr != NULL) { + g_hash_table_iter_init (&it, gr->symbols); - beg ++; - } + while (g_hash_table_iter_next (&it, &k, &v)) { + sdef = v; - nrd->comp = cd->composite; - nrd->parent = atom->parent; + if (sdef->score < 0) { + rc = rspamd_composite_process_single_symbol (cd, sdef->name, &ms); - if (rd == NULL) { - DL_APPEND (rd, nrd); - g_hash_table_insert (cd->symbols_to_remove, (gpointer)ms->name, rd); + if (rc) { + rspamd_composite_process_symbol_removal (atom, + cd, + ms, + beg); + } + } + } } - else { - DL_APPEND (rd, nrd); + } + else { + rc = rspamd_composite_process_single_symbol (cd, sym, &ms); + + if (rc) { + rspamd_composite_process_symbol_removal (atom, + cd, + ms, + beg); } }