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

[email protected]
Newsgroups gmane.mail.spam.spamassassin.cvs
Message-ID <176055595386.2063198.5501729013599233114@svn02-us-east.apache.org>
Author: fkento
Date: Wed Oct 15 19:19:13 2025
New Revision: 1929159

Log:
Add support for nested anchor tags

Added:
   spamassassin/trunk/t/html_nested_anchors.t
Modified:
   spamassassin/trunk/MANIFEST
   spamassassin/trunk/lib/Mail/SpamAssassin/HTML.pm

Modified: spamassassin/trunk/MANIFEST
==============================================================================
--- spamassassin/trunk/MANIFEST	Wed Oct 15 14:28:12 2025	(r1929158)
+++ spamassassin/trunk/MANIFEST	Wed Oct 15 19:19:13 2025	(r1929159)
@@ -555,6 +555,7 @@ t/header.t
 t/header_utf8.t
 t/hashbl.t
 t/html_colors.t
+t/html_nested_anchors.t
 t/html_obfu.t
 t/html_utf8.t
 t/html_visibility.t

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/HTML.pm
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/HTML.pm	Wed Oct 15 14:28:12 2025	(r1929158)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/HTML.pm	Wed Oct 15 19:19:13 2025	(r1929159)
@@ -125,6 +125,7 @@ sub new {
   $self->{SA_character_semantics_input} = $character_semantics_input;
   $self->{SA_encode_results} =
     $character_semantics_input && !$character_semantics_output;
+  $self->{anchor_refs} = [];
   $self;
 }
 
@@ -343,6 +344,7 @@ sub html_tag {
     }
     # end tags
     else {
+      pop(@{ $self->{anchor_refs} }) if $tag eq "a";
       $self->{closed_html} = 1 if $tag eq "html";
       $self->{closed_body} = 1 if $tag eq "body";
     }
@@ -859,9 +861,7 @@ sub html_tests {
     }
   }
   if ($tag eq "img" && exists $self->{inside}{a} && $self->{inside}{a} > 0) {
-    my $uri = $self->{anchor_last};
-    utf8::encode($uri) if $self->{SA_encode_results};
-    $self->{uri}->{$uri}->{anchor_text}->[-1] .= "<img>\n";
+    $$_ .= "<img>\n" for (@{$self->{anchor_refs}});
     $self->{anchor}->[-1] .= "<img>\n";
   }
 
@@ -896,11 +896,13 @@ sub html_tests {
 
   # special text delimiters - <a> and <title>
   if ($tag eq "a") {
-    my $uri = $self->{anchor_last} =
+    my $uri =
       (exists $attr->{href} ? $self->canon_uri($attr->{href}) : "");
     utf8::encode($uri) if $self->{SA_encode_results};
     push(@{$self->{uri}->{$uri}->{anchor_text}}, '');
     push(@{$self->{anchor}}, '');
+    # keep track of nested anchors (max depth 10)
+    push(@{$self->{anchor_refs}}, \($self->{uri}->{$uri}->{anchor_text}->[-1])) if @{$self->{anchor_refs}} < 10;
   }
   if ($tag eq "title") {
     $self->{title_index}++;
@@ -977,10 +979,7 @@ sub html_text {
 
   # text that is part of body and also stored separately
   if (exists $self->{inside}{a} && $self->{inside}{a} > 0) {
-    # this doesn't worry about nested anchors
-    my $uri = $self->{anchor_last};
-    utf8::encode($uri) if $self->{SA_encode_results};
-    $self->{uri}->{$uri}->{anchor_text}->[-1] .= $text;
+    $$_ .= $text for (@{$self->{anchor_refs}});
     $self->{anchor}->[-1] .= $text;
   }
   if (exists $self->{inside}{title} && $self->{inside}{title} > 0) {

Added: spamassassin/trunk/t/html_nested_anchors.t
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ spamassassin/trunk/t/html_nested_anchors.t	Wed Oct 15 19:19:13 2025	(r1929159)
@@ -0,0 +1,45 @@
+#!/usr/bin/perl -T
+use strict;
+use warnings;
+use lib '.'; use lib 't';
+use SATest; sa_t_init("html_nested_anchors");
+use Mail::SpamAssassin::HTML;
+use Test::More;
+
+my @tests = (
+    {
+        html => '<a href="#one">foo<a href="#two">bar</a>baz</a>',
+        uris => {
+            '#one' => {
+                types       => { 'a' => 1 },
+                anchor_text => ['foobarbaz'],
+            },
+            '#two' => {
+                types       => { 'a' => 1 },
+                anchor_text => ['bar'],
+            }
+        }
+    },
+    {
+        html => '<a href="#one">foo<a href="#one">bar</a>baz</a>',
+        uris => {
+            '#one' => {
+                types       => { 'a' => 1 },
+                anchor_text => ['foobarbaz', 'bar'],
+            },
+        }
+    },
+);
+
+plan tests => scalar @tests;
+
+foreach my $test (@tests) {
+    my $html = $test->{html};
+
+    my $html_obj = Mail::SpamAssassin::HTML->new(0, 0);
+    $html_obj->parse($html);
+
+    my $uris = $html_obj->{results}->{uri_detail};
+    is_deeply($uris, $test->{uris}, "URI details match for HTML: $html");
+
+}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.