svn commit: r1933141 - in spamassassin/trunk: lib/Mail/SpamAssassin t

[email protected] Fri, 17 Apr 2026 20:15:47 -0000
Newsgroups gmane.mail.spam.spamassassin.cvs
Message-ID <177645694705.3934632.13615829425087898149@svn03-he-fi>
Author: fkento
Date: Fri Apr 17 20:15:46 2026
New Revision: 1933141

Log:
Large negative absolute positioning is invisible text

Modified:
   spamassassin/trunk/lib/Mail/SpamAssassin/HTML.pm
   spamassassin/trunk/t/html_visibility.t

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/HTML.pm
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/HTML.pm	Fri Apr 17 20:10:04 2026	(r1933140)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/HTML.pm	Fri Apr 17 20:15:46 2026	(r1933141)
@@ -815,6 +815,7 @@ sub html_font_invisible {
   my $display = $self->{text_style}[-1]->{style_display};
   my $visibility = $self->{text_style}[-1]->{style_visibility};
   my $transform = $self->{text_style}[-1]->{style_transform};
+  my $position = $self->{text_style}[-1]->{style_position};
 
   # size too small
   if ($font_size < 8) {
@@ -839,6 +840,19 @@ sub html_font_invisible {
     return 1;
   }
 
+  # <div style="position: absolute; left: -9999px"> — element positioned far off-screen
+  # Only left/top are reliable: negative bottom pushes down (scrollable),
+  # negative right pushes past the right edge (may be visible on wide viewports)
+  if ($position && $position =~ /^(?:absolute|fixed)\b/i) {
+    for my $prop (qw( style_left style_top )) {
+      my $val = $self->{text_style}[-1]->{$prop};
+      next unless defined $val;
+      if ($val =~ /^\s*(-\d+(?:\.\d+)?)\s*(?:px|pt|em|rem|ex|%)?\s*$/i) {
+        return 1 if $1 <= -1000;
+      }
+    }
+  }
+
   # low-contrast text
   # the text is very difficult to read if the distance is under 12,
   # a limit of 14 to 16 might be okay if the usage significantly

Modified: spamassassin/trunk/t/html_visibility.t
==============================================================================
--- spamassassin/trunk/t/html_visibility.t	Fri Apr 17 20:10:04 2026	(r1933140)
+++ spamassassin/trunk/t/html_visibility.t	Fri Apr 17 20:15:46 2026	(r1933141)
@@ -237,6 +237,36 @@ my @tests = (
         visibility         => 'visible',
         font_invalid_color => 0,
     },
+    {
+        html               => '<div style="position: absolute; left: -9999px">X</div>',
+        visibility         => 'invisible',
+        font_invalid_color => 0,
+    },
+    {
+        html               => '<div style="position:absolute;left:-9999px">X</div>',
+        visibility         => 'invisible',
+        font_invalid_color => 0,
+    },
+    {
+        html               => '<div style="POSITION: ABSOLUTE; LEFT: -9999PX">X</div>',
+        visibility         => 'invisible',
+        font_invalid_color => 0,
+    },
+    {
+        html               => '<div style="position: fixed; top: -9999px">X</div>',
+        visibility         => 'invisible',
+        font_invalid_color => 0,
+    },
+    {
+        html               => '<div style="position: absolute; left: -50px">X</div>',
+        visibility         => 'visible',
+        font_invalid_color => 0,
+    },
+    {
+        html               => '<div style="position: absolute; left: 50px">X</div>',
+        visibility         => 'visible',
+        font_invalid_color => 0,
+    },
 );
 
 plan tests => scalar @tests * 2;