svn commit: r1936344 - in spamassassin/trunk/lib/Mail/SpamAssassin: . Handler

[email protected] Mon, 20 Jul 2026 06:03:43 -0000
Newsgroups gmane.mail.spam.spamassassin.cvs
Message-ID <178452742358.2497351.529092008113987016@svn03-he-fi>
Author: fkento
Date: Mon Jul 20 06:03:43 2026
New Revision: 1936344

Log:
Extract HTML URIs in the HTML handler instead of _process_html_uri_list

  Move HTML URI harvesting out of PerMsgStatus::_process_html_uri_list and
  into Handler::HTML::handle_html, so that:

    * URIs are extracted from synthetic HTML parts too. Handlers can emit
      child parts that never appear in the original MIME tree. The old walk
      iterated metadata->{html_all}, which only holds parts from the parsed
      message tree, so it never saw these. Harvesting as each part is
      rendered by its handler covers synthetic parts as well.

    * HTML-specific code lives in the HTML handler, alongside the rendering
      it depends on, rather than in PerMsgStatus.

  handle_html now walks html_results->{uri_detail} and calls
  add_uri_detail_list (type 'html', copying anchor_text), mirroring what
  _process_html_uri_list did.
  
  get_uri_detail_list now ensures apply_handlers has run before assembling
  the list, so a caller fetching URIs without a full scan still gets HTML
  URIs.

Modified:
   spamassassin/trunk/lib/Mail/SpamAssassin/Handler/HTML.pm
   spamassassin/trunk/lib/Mail/SpamAssassin/PerMsgStatus.pm

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Handler/HTML.pm
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Handler/HTML.pm	Mon Jul 20 05:18:05 2026	(r1936343)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Handler/HTML.pm	Mon Jul 20 06:03:43 2026	(r1936344)
@@ -91,6 +91,26 @@ sub handle_html {
 
   my $results = $node->{html_results}  or return [];
 
+  # Harvest URIs the HTML parser found into the URI detail list (type 'html')
+  my $detail = $results->{uri_detail} || {};
+  $pms->{'uri_truncated'} = 1 if $results->{uri_truncated};
+  while (my ($uri, $info) = each %$detail) {
+    if ($pms->add_uri_detail_list($uri, $info->{types}, 'html', 0)) {
+      # Copy and uniq the anchor text, collapsing whitespace (Bug 8268/8310).
+      if (exists $info->{anchor_text}) {
+        for (@{$info->{anchor_text}}) {
+          s/^\s+|\s+$//g;
+          s/\s+/ /g;
+          utf8::encode($_) if utf8::is_utf8($_);
+        }
+        my %seen;
+        foreach (grep { !$seen{$_}++ } @{$info->{anchor_text}}) {
+          push @{$pms->{uri_detail_list}->{$uri}->{anchor_text}}, $_;
+        }
+      }
+    }
+  }
+
   my @parts;
 
   # Typed pseudo-parts the HTML parser extracted, each already a

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/PerMsgStatus.pm
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/PerMsgStatus.pm	Mon Jul 20 05:18:05 2026	(r1936343)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/PerMsgStatus.pm	Mon Jul 20 06:03:43 2026	(r1936344)
@@ -2691,12 +2691,14 @@ sub get_uri_detail_list {
   }
   $self->{uri_detail_list_run} = 1;
 
+  # Ensure MIME-part handlers have run
+  $self->{msg}->apply_handlers($self);
+
   my $timer = $self->{main}->time_method("get_uri_detail_list");
 
   # process text parsed uris
   $self->_process_text_uri_list();
-  # process html uris
-  $self->_process_html_uri_list();
+  # HTML URIs were added by the HTML handler above (see apply_handlers).
   # process dkim uris
   $self->_process_dkim_uri_list();
 
@@ -2806,36 +2808,6 @@ sub _process_text_uri_list {
     }
   }
 }
-
-sub _process_html_uri_list {
-  my ($self) = @_;
-
-  # get URIs from HTML parsing
-  # use the metadata version since $self->{html_all} may not be setup
-  foreach my $html (@{$self->{msg}->{metadata}->{html_all}}) {
-    my $detail = $html->{uri_detail} || { };
-    $self->{'uri_truncated'} = 1 if $html->{uri_truncated};
-
-    # canonicalize the HTML parsed URIs
-    while(my($uri, $info) = each %{ $detail }) {
-      if ($self->add_uri_detail_list($uri, $info->{types}, 'html', 0)) {
-        # Need also to copy and uniq anchor text
-        if (exists $info->{anchor_text}) {
-          # Bug 8268: Collapse whitespace
-          for (@{$info->{anchor_text}}) {
-            s/^\s+|\s+$//g;
-            s/\s+/ /g;
-            utf8::encode($_) if utf8::is_utf8($_);  # Bug 8310: UTF-8 encode anchor_text
-          }
-          my %seen;
-          foreach (grep { !$seen{$_}++ } @{$info->{anchor_text}}) {
-            push @{$self->{uri_detail_list}->{$uri}->{anchor_text}}, $_;
-          }
-        }
-      }
-    }
-  }
-}
 
 sub _process_dkim_uri_list {
   my ($self) = @_;