]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
fix: properly set bayes class labels to S and H for class spam and ham class names...
authorDmitriy Alekseev <1865999+dragoangel@users.noreply.github.com>
Tue, 24 Feb 2026 17:19:40 +0000 (18:19 +0100)
committerDmitriy Alekseev <1865999+dragoangel@users.noreply.github.com>
Tue, 24 Feb 2026 17:19:40 +0000 (18:19 +0100)
Signed-off-by: Dmitriy Alekseev <1865999+dragoangel@users.noreply.github.com>
lualib/redis_scripts/bayes_learn.lua
src/libstat/backends/redis_backend.cxx
src/plugins/lua/bayes_expiry.lua

index 3f8ee1cbc7bbbaa89b57156e8866ca62b1ef42a6..8fa984e08bba1deacbf98dd73a6aa5a17f24a9ae 100644 (file)
@@ -18,17 +18,17 @@ if ARGV[5] then
   text_tokens = cmsgpack.unpack(ARGV[5])
 end
 
--- Handle backward compatibility for boolean values
-if class_label == 'true' then
-  class_label = 'S' -- spam
-elseif class_label == 'false' then
-  class_label = 'H' -- ham
+-- Handle RS_<ID> HASH booleans and full class name strings for backward compatibility
+if class_label == 'true' or class_label == 'spam' then
+  class_label = 'S'
+elseif class_label == 'false' or class_label == 'ham' then
+  class_label = 'H'
 end
 
 local hash_key = class_label
 local learned_key = 'learns_' .. string.lower(class_label)
 
--- Handle legacy keys for backward compatibility
+-- Handle RS HASH keys for backward compatibility
 if class_label == 'S' then
   learned_key = 'learns_spam'
 elseif class_label == 'H' then
index 8489947e361e1eb382c31e74dc0bb07828810956..9e2867f2639bfd52a9bdb299ae9cc05d90f7c661 100644 (file)
@@ -191,6 +191,10 @@ rspamd_redis_stat_quark(void)
 
 /*
  * Get the class label for a statfile (for multi-class support)
+ * Returns the Redis hash field name to use for this class.  "spam" and "ham"
+ * always map to the legacy single-char labels "S" and "H" so that existing
+ * Redis token data (stored under those field names) remains readable after a
+ * config migration from `spam = true/false` to explicit `class = "spam"/"ham"`.
  */
 static const char *
 get_class_label(struct rspamd_statfile_config *stcf)
@@ -201,16 +205,25 @@ get_class_label(struct rspamd_statfile_config *stcf)
                if (label) {
                        return label;
                }
-               /* If no label mapping found, use class name directly */
-               return stcf->class_name;
+               /* No mapping found — fall through to backward-compat checks below */
        }
 
-       /* For multiclass without explicit label mapping, use class_name directly */
-       if (stcf->class_name && !stcf->is_spam_converted) {
-               return stcf->class_name;
+       if (stcf->class_name) {
+               /* Map canonical binary class names to their legacy Redis field names */
+               if (strcmp(stcf->class_name, "spam") == 0) {
+                       return "S";
+               }
+               if (strcmp(stcf->class_name, "ham") == 0) {
+                       return "H";
+               }
+
+               /* True multiclass name (not spam/ham) — use the class name as the field */
+               if (!stcf->is_spam_converted) {
+                       return stcf->class_name;
+               }
        }
 
-       /* Fallback to legacy binary classification */
+       /* Final fallback: legacy binary is_spam flag */
        return stcf->is_spam ? "S" : "H";
 }
 
index 69b0f93266fd35c7aaf250835e10a60432a73f46..10ac8d2a309a94d100e688375ed7200df6605f54 100644 (file)
@@ -73,6 +73,8 @@ local function check_redis_classifier(cls, cfg)
 
       if class_name then
         class_symbols[class_name] = symbol
+        logger.debugm(N, rspamd_config,
+          'check_statfile_table: found class_name=%s and its symbol=%s', class_name, symbol)
       end
     end
 
@@ -284,6 +286,12 @@ local expiry_script = [[
       -- Parse hash data into class counts
       for i = 1, #hash_data, 2 do
         local class_label = hash_data[i]
+        -- Handle RS_<ID> HASH short class names for backward compatibility
+        if class_label == 'S' then
+          class_label = 'spam'
+        elseif class_label == 'H' then
+          class_label = 'ham'
+        end
         local count = tonumber(hash_data[i + 1]) or 0
         class_counts[class_label] = count
         total = total + count