You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by fk...@apache.org on 2026/09/17 22:19:44 UTC

svn commit: r1938338 - spamassassin/trunk/lib/Mail/SpamAssassin/Plugin

Author: fkento
Date: Thu Sep 17 22:19:44 2026
New Revision: 1938338

Log:
Bug 8415: FreeMail: stop clobbering the cached body array

_parse_body() aliased $_ to the elements of the array returned by
get_decoded_stripped_body_text_array(), which is the message's cached
rendered body. The s/// calls that blank out addresses we don't want to
harvest therefore rewrote the body in place, permanently, so every body
rule evaluated after FreeMail saw a corrupted message: addresses in <>
were gone, bare addresses followed by a short lowercase word and a colon
took that trailing word with them, and any URL containing @ or %40 was
stripped. Forwarded mail was affected the most.

Copy each line into a lexical before stripping so the harvesting logic is
unchanged but the cached body is left alone.

Modified:
   spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/FreeMail.pm

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/FreeMail.pm
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/FreeMail.pm	Thu Sep 17 21:17:38 2026	(r1938337)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/FreeMail.pm	Thu Sep 17 22:19:44 2026	(r1938338)
@@ -365,12 +365,16 @@ sub _parse_body {
         # have to do this way since get_uri_detail_list doesn't know what mails are inside <>
         my $body = $pms->get_decoded_stripped_body_text_array();
         BODY: foreach (@$body) {
+            # Bug 8415: Work on a copy: @$body is the message's cached rendered body
+            # array, so the strips below would otherwise destroy it for
+            # every rule that runs after us
+            my $line = $_;
             # strip urls with possible emails inside
-            s{<?https?://\S{0,255}(?:\@|%40)\S{0,255}}{ }gi;
+            $line =~ s{<?https?://\S{0,255}(?:\@|%40)\S{0,255}}{ }gi;
             # strip emails contained in <>, not mailto:
             # also strip ones followed by quote-like "wrote:" (but not fax: and tel: etc)
-            s{<?(?<!mailto:)$self->{email_regex}(?:>|\s{1,10}(?!(?:fa(?:x|csi)|tel|phone|e?-?mail))[a-z]{2,11}:)}{ }gi;
-            while (/$self->{email_regex}/g) {
+            $line =~ s{<?(?<!mailto:)$self->{email_regex}(?:>|\s{1,10}(?!(?:fa(?:x|csi)|tel|phone|e?-?mail))[a-z]{2,11}:)}{ }gi;
+            while ($line =~ /$self->{email_regex}/g) {
                 my $email = lc($1);
                 utf8::encode($email) if utf8::is_utf8($email); # chars to UTF-8
                 push(@body_emails, $email) unless $seen{$email};