]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Minor] Refactor fuzzy flag collision detection into parse-time check 6027/head
authorAlexander Moisseev <moiseev@mezonplus.ru>
Fri, 8 May 2026 19:18:01 +0000 (22:18 +0300)
committerAlexander Moisseev <moiseev@mezonplus.ru>
Fri, 8 May 2026 19:18:01 +0000 (22:18 +0300)
src/plugins/fuzzy_check.c

index 50f6d49d48922404e0d749a343848f4dc5cf00d7..7dbf786b9a48de214d4bfd270c3bc668557f5ded 100644 (file)
@@ -162,6 +162,7 @@ struct fuzzy_ctx {
        int cleanup_rules_ref;
        uint32_t retransmits;
        gboolean enabled;
+       GHashTable *writable_flags; /* flag -> rule_name, for collision detection */
 };
 
 static inline uint8_t
@@ -2274,6 +2275,30 @@ fuzzy_parse_rule(struct rspamd_config *cfg, const ucl_object_t *obj,
        rspamd_mempool_add_destructor(cfg->cfg_pool, fuzzy_free_rule,
                                                                  rule);
 
+       if (rule->mode != fuzzy_rule_read_only && fuzzy_module_ctx->writable_flags != NULL) {
+               GHashTableIter fit;
+               gpointer fk, fv;
+               g_hash_table_iter_init(&fit, rule->mappings);
+
+               while (g_hash_table_iter_next(&fit, &fk, &fv)) {
+                       const char *existing = g_hash_table_lookup(fuzzy_module_ctx->writable_flags, fk);
+
+                       if (existing != NULL) {
+                               msg_warn_config(
+                                       "fuzzy flag %d is used by both writable rules '%s' and '%s'; "
+                                       "write operations will be sent to all matching rules — "
+                                       "use unique flags or set `read_only = true` on rules that should not receive writes",
+                                       GPOINTER_TO_INT(fk),
+                                       existing,
+                                       rule->name ? rule->name : "(unnamed)");
+                       }
+                       else {
+                               g_hash_table_insert(fuzzy_module_ctx->writable_flags, fk,
+                                                                       (gpointer) (rule->name ? rule->name : "(unnamed)"));
+                       }
+               }
+       }
+
        return 0;
 }
 
@@ -2886,6 +2911,11 @@ int fuzzy_check_module_config(struct rspamd_config *cfg, bool validate)
                                                                 1,
                                                                 1);
 
+               fuzzy_module_ctx->writable_flags = g_hash_table_new(g_direct_hash, g_direct_equal);
+               rspamd_mempool_add_destructor(cfg->cfg_pool,
+                                                                         (rspamd_mempool_destruct_t) g_hash_table_unref,
+                                                                         fuzzy_module_ctx->writable_flags);
+
                /*
                 * Here we can have 2 possibilities:
                 *
@@ -2944,44 +2974,6 @@ int fuzzy_check_module_config(struct rspamd_config *cfg, bool validate)
        msg_info_config("init internal fuzzy_check module, %d rules loaded",
                                        nrules);
 
-       /* Check for flag collisions across writable rules */
-       if (fuzzy_module_ctx->fuzzy_rules != NULL && fuzzy_module_ctx->fuzzy_rules->len > 1) {
-               GHashTable *writable_flag_rules = g_hash_table_new(g_direct_hash, g_direct_equal);
-               unsigned int ri;
-               struct fuzzy_rule *wrule;
-
-               PTR_ARRAY_FOREACH(fuzzy_module_ctx->fuzzy_rules, ri, wrule)
-               {
-                       if (wrule->mode == fuzzy_rule_read_only) {
-                               continue;
-                       }
-
-                       GHashTableIter flag_it;
-                       gpointer fk, fv;
-                       g_hash_table_iter_init(&flag_it, wrule->mappings);
-
-                       while (g_hash_table_iter_next(&flag_it, &fk, &fv)) {
-                               const char *existing_rule_name = g_hash_table_lookup(writable_flag_rules, fk);
-
-                               if (existing_rule_name != NULL) {
-                                       msg_warn_config(
-                                               "fuzzy flag %d is used by both writable rules '%s' and '%s'; "
-                                               "write operations will be sent to all matching rules — "
-                                               "use unique flags or set `read_only = true` on rules that should not receive writes",
-                                               GPOINTER_TO_INT(fk),
-                                               existing_rule_name,
-                                               wrule->name ? wrule->name : "(unnamed)");
-                               }
-                               else {
-                                       g_hash_table_insert(writable_flag_rules, fk,
-                                                                               (gpointer) (wrule->name ? wrule->name : "(unnamed)"));
-                               }
-                       }
-               }
-
-               g_hash_table_destroy(writable_flag_rules);
-       }
-
        /* Register global methods */
        lua_getglobal(L, "rspamd_plugins");