rep.flag = sqlite3_column_int (
prepared_stmts[RSPAMD_FUZZY_BACKEND_CHECK].stmt, 2);
- if (!(rep.flag & flags_mask)) {
- rep.flag = (1U << rep.flag) | flags_mask;
+ if (!(rep.flag & flags_mask) && rep.flag > 0) {
+ rep.flag = (1U << (rep.flag - 1)) | flags_mask;
}
}
}
prepared_stmts[RSPAMD_FUZZY_BACKEND_GET_DIGEST_BY_ID].stmt,
3);
- if (!(rep.flag & flags_mask)) {
- rep.flag = (1U << rep.flag) | flags_mask;
+ if (!(rep.flag & flags_mask) && rep.flag > 0) {
+ rep.flag = (1U << (rep.flag - 1)) | flags_mask;
}
}
}
return FALSE;
}
- if (cmd->flag > 31) {
+ if (cmd->flag > 31 || cmd->flag == 0) {
msg_err_fuzzy_backend ("flag more than 31 is no longer supported");
return FALSE;
}
2);
rspamd_fuzzy_backend_cleanup_stmt (backend, RSPAMD_FUZZY_BACKEND_CHECK);
- if ((flag & cmd->flag) == cmd->flag) {
+ if (flag & (1U << (cmd->flag - 1))) {
/* We need to increase weight */
rc = rspamd_fuzzy_backend_run_stmt (backend, TRUE,
RSPAMD_FUZZY_BACKEND_UPDATE,
/* We need to relearn actually */
if (flag & flags_mask) {
/* This is already new format */
- flag |= cmd->flag;
+ flag |= (1U << (cmd->flag - 1));
}
else {
/* Convert to the new format */
- if (flag > 31) {
+ if (flag > 31 || flag == 0) {
msg_warn_fuzzy_backend ("storage had flag more than 31, remove "
"it");
flag = cmd->flag | flags_mask;
}
else {
- flag = (1U << flag) | cmd->flag | flags_mask;
+ flag = (1U << (flag - 1)) | (1U << (cmd->flag - 1)) | flags_mask;
}
}
rc = rspamd_fuzzy_backend_run_stmt (backend, TRUE,
RSPAMD_FUZZY_BACKEND_UPDATE_FLAG,
(gint64) cmd->value,
- (gint64) cmd->flag,
+ (gint64) flag,
cmd->digest);
if (rc != SQLITE_OK) {
rspamd_fuzzy_backend_cleanup_stmt (backend, RSPAMD_FUZZY_BACKEND_CHECK);
rc = rspamd_fuzzy_backend_run_stmt (backend, FALSE,
RSPAMD_FUZZY_BACKEND_INSERT,
- (gint) (1U << cmd->flag),
+ (gint) (1U << (cmd->flag - 1)),
cmd->digest,
(gint64) cmd->value,
(gint64) timestamp);
return NULL;
}
+static void
+fuzzy_insert_result (struct fuzzy_client_session *session,
+ const struct rspamd_fuzzy_reply *rep,
+ struct rspamd_fuzzy_cmd *cmd, guint flag)
+{
+ const gchar *symbol;
+ struct fuzzy_mapping *map;
+ struct rspamd_task *task = session->task;
+ double nval;
+ guchar buf[2048];
+
+ /* Get mapping by flag */
+ if ((map =
+ g_hash_table_lookup (session->rule->mappings,
+ GINT_TO_POINTER (rep->flag))) == NULL) {
+ /* Default symbol and default weight */
+ symbol = session->rule->symbol;
+
+ }
+ else {
+ /* Get symbol and weight from map */
+ symbol = map->symbol;
+ }
+
+
+ /*
+ * Hash is assumed to be found if probability is more than 0.5
+ * In that case `value` means number of matches
+ * Otherwise `value` means error code
+ */
+
+ nval = fuzzy_normalize (rep->value,
+ session->rule->max_score);
+ nval *= rep->prob;
+ msg_info_task (
+ "found fuzzy hash %*xs with weight: "
+ "%.2f, in list: %s:%d%s",
+ rspamd_fuzzy_hash_len, cmd->digest,
+ nval,
+ symbol,
+ rep->flag,
+ map == NULL ? "(unknown)" : "");
+ if (map != NULL || !session->rule->skip_unknown) {
+ rspamd_snprintf (buf,
+ sizeof (buf),
+ "%d:%*xs:%.2f",
+ rep->flag,
+ rspamd_fuzzy_hash_len, cmd->digest,
+ rep->prob,
+ nval);
+ rspamd_task_insert_result_single (session->task,
+ symbol,
+ nval,
+ g_list_prepend (NULL,
+ rspamd_mempool_strdup (
+ session->task->task_pool,
+ buf)));
+ }
+}
+
/* Fuzzy check callback */
static void
fuzzy_check_io_callback (gint fd, short what, void *arg)
struct fuzzy_client_session *session = arg;
const struct rspamd_fuzzy_reply *rep;
struct rspamd_task *task;
- struct fuzzy_mapping *map;
guchar buf[2048], *p;
- const gchar *symbol;
struct fuzzy_cmd_io *io;
struct rspamd_fuzzy_cmd *cmd = NULL;
guint i;
gint r;
- double nval;
+
enum {
return_error = 0,
return_want_more,
while ((rep = fuzzy_process_reply (&p, &r,
session->commands, session->rule, &cmd)) != NULL) {
- /* Get mapping by flag */
- if ((map =
- g_hash_table_lookup (session->rule->mappings,
- GINT_TO_POINTER (rep->flag))) == NULL) {
- /* Default symbol and default weight */
- symbol = session->rule->symbol;
-
- }
- else {
- /* Get symbol and weight from map */
- symbol = map->symbol;
- }
-
-
- /*
- * Hash is assumed to be found if probability is more than 0.5
- * In that case `value` means number of matches
- * Otherwise `value` means error code
- */
if (rep->prob > 0.5) {
- nval = fuzzy_normalize (rep->value,
- session->rule->max_score);
- nval *= rep->prob;
- msg_info_task (
- "found fuzzy hash %*xs with weight: "
- "%.2f, in list: %s:%d%s",
- rspamd_fuzzy_hash_len, cmd->digest,
- nval,
- symbol,
- rep->flag,
- map == NULL ? "(unknown)" : "");
- if (map != NULL || !session->rule->skip_unknown) {
- rspamd_snprintf (buf,
- sizeof (buf),
- "%d:%*xs:%.2f",
- rep->flag,
- rspamd_fuzzy_hash_len, cmd->digest,
- rep->prob,
- nval);
- rspamd_task_insert_result_single (session->task,
- symbol,
- nval,
- g_list_prepend (NULL,
- rspamd_mempool_strdup (
- session->task->task_pool,
- buf)));
+ if (rep->flag & (1U << 31)) {
+ /* Multi-flag */
+ for (i = 0; i < 31; i ++) {
+ if ((1U << i) & rep->flag) {
+ fuzzy_insert_result (session, rep, cmd, i + 1);
+ }
+ }
+ }
+ else {
+ fuzzy_insert_result (session, rep, cmd, rep->flag);
}
}
else if (rep->value == 403) {
msg_info_task (
- "fuzzy check error for %s(%d): forbidden",
- symbol,
+ "fuzzy check error for %d: forbidden",
rep->flag);
}
else if (rep->value != 0) {
msg_info_task (
- "fuzzy check error for %s(%d): unknown error (%d)",
- symbol,
+ "fuzzy check error for %d: unknown error (%d)",
rep->flag,
rep->value);
}
- /* Not found */
ret = return_finished;
}