]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Fix] R_PARTS_DIFFER: handle empty alternative parts
authorVsevolod Stakhov <vsevolod@rspamd.com>
Mon, 2 Feb 2026 14:27:16 +0000 (14:27 +0000)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Mon, 2 Feb 2026 14:27:16 +0000 (14:27 +0000)
Previously, R_PARTS_DIFFER only triggered when both text/html and
text/plain parts had content. When one part was empty (e.g., empty
HTML with non-empty plain text), the distance was never calculated.

Now detect when exactly one part is empty and treat it as 100%
difference, which will trigger R_PARTS_DIFFER with maximum score.

src/libmime/message.c

index 0a7a445a18d325ad95de6f4e6ef4db550cc87ed9..8bd2c11b5c01f4bf0b3ea93621935b3502583266 100644 (file)
@@ -1909,6 +1909,38 @@ void rspamd_message_process(struct rspamd_task *task)
                                                                                                        NULL);
                                        }
                                }
+                               else if (IS_TEXT_PART_EMPTY(p1) != IS_TEXT_PART_EMPTY(p2)) {
+                                       /*
+                                        * One part is empty, another is not - this is 100% difference
+                                        */
+                                       struct rspamd_mime_text_part *non_empty =
+                                               IS_TEXT_PART_EMPTY(p1) ? p2 : p1;
+
+                                       if (non_empty->normalized_hashes &&
+                                               non_empty->normalized_hashes->len > 0) {
+                                               tw = non_empty->normalized_hashes->len;
+
+                                               msg_debug_task(
+                                                       "one part is empty, another has %d words, "
+                                                       "got diff between parts of 1.0",
+                                                       tw);
+
+                                               pdiff = rspamd_mempool_alloc(task->task_pool,
+                                                                                                        sizeof(double));
+                                               *pdiff = 1.0;
+                                               rspamd_mempool_set_variable(task->task_pool,
+                                                                                                       "parts_distance",
+                                                                                                       pdiff,
+                                                                                                       NULL);
+                                               ptw = rspamd_mempool_alloc(task->task_pool,
+                                                                                                  sizeof(int));
+                                               *ptw = tw;
+                                               rspamd_mempool_set_variable(task->task_pool,
+                                                                                                       "total_words",
+                                                                                                       ptw,
+                                                                                                       NULL);
+                                       }
+                               }
                        }
                }
                else {