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/03/21 04:31:45 UTC
svn commit: r1932427 - spamassassin/trunk/lib/Mail/SpamAssassin/Plugin
Author: fkento
Date: Sat Mar 21 04:31:44 2026
New Revision: 1932427
Log:
DMARC plugin: fix undef warnings when ARC overrides DMARC result
When ARC overrides a DMARC fail to pass, the code then tried to look up
the published policy via $result->published->p, which dies because the
original validation was a failure with no pass-path policy. This left
dmarc_policy unset, causing 'uninitialized value' warnings in the eval
closures and a logged exception.
Fix by setting dmarc_policy from the original disposition when ARC
overrides, and wrapping $result->published->p in eval for the normal
pass path. Added defined checks on dmarc_policy in all eval closures
as a safety net.
Modified:
spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/DMARC.pm
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/DMARC.pm
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/DMARC.pm Sat Mar 21 04:20:02 2026 (r1932426)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/DMARC.pm Sat Mar 21 04:31:44 2026 (r1932427)
@@ -159,6 +159,7 @@ sub check_dmarc_pass {
my $result = sub {
defined $pms->{dmarc_result} &&
$pms->{dmarc_result} eq 'pass' &&
+ defined $pms->{dmarc_policy} &&
$pms->{dmarc_policy} ne 'no policy available';
};
@@ -171,6 +172,7 @@ sub check_dmarc_reject {
my $result = sub {
defined $pms->{dmarc_result} &&
$pms->{dmarc_result} eq 'fail' &&
+ defined $pms->{dmarc_policy} &&
$pms->{dmarc_policy} eq 'reject';
};
@@ -183,6 +185,7 @@ sub check_dmarc_quarantine {
my $result = sub {
defined $pms->{dmarc_result} &&
$pms->{dmarc_result} eq 'fail' &&
+ defined $pms->{dmarc_policy} &&
$pms->{dmarc_policy} eq 'quarantine';
};
@@ -195,6 +198,7 @@ sub check_dmarc_none {
my $result = sub {
defined $pms->{dmarc_result} &&
$pms->{dmarc_result} eq 'fail' &&
+ defined $pms->{dmarc_policy} &&
$pms->{dmarc_policy} eq 'none';
};
@@ -206,6 +210,7 @@ sub check_dmarc_missing {
my $result = sub {
defined $pms->{dmarc_result} &&
+ defined $pms->{dmarc_policy} &&
$pms->{dmarc_policy} eq 'no policy available';
};
@@ -356,28 +361,24 @@ sub _check_dmarc {
$result->{result} = 'pass';
$result->reason->[0]{type} = 'local_policy';
$result->reason->[0]{comment} = "arc=pass (trusted ARC sealer)";
- }
-
- if (defined $pms->{dmarc_result}) {
- if ($pms->{conf}->{dmarc_save_reports}) {
- my $rua = eval { $result->published()->rua(); };
- if (defined $rua && index($rua, 'mailto:') >= 0) {
- eval { $dmarc->save_aggregate(); };
- if ($@) {
- info("report could not be saved: $@");
- } else {
- dbg("report will be sent to $rua");
- }
- }
- }
-
+ # ARC override changed result to pass, set policy from original
+ # disposition and skip normal policy lookup which would fail
+ $pms->{dmarc_policy} = $result->disposition || 'no policy available';
+ dbg("result: pass (ARC override), original policy: $pms->{dmarc_policy}");
+ } elsif (defined $pms->{dmarc_result}) {
if (defined $result->reason->[0]{comment} &&
$result->reason->[0]{comment} eq 'too many policies') {
dbg("result: no policy available (too many policies)");
$pms->{dmarc_policy} = 'no policy available';
} elsif ($result->result eq 'pass') {
dbg("result: pass");
- $pms->{dmarc_policy} = $result->published->p;
+ my $policy = eval { $result->published->p };
+ if (!defined $policy) {
+ dbg("result: pass but no published policy available");
+ $pms->{dmarc_policy} = 'no policy available';
+ return;
+ }
+ $pms->{dmarc_policy} = $policy;
} elsif ($result->result ne 'none') {
dbg("result: $result->{result}, disposition: $result->{disposition}, dkim: $result->{dkim}, spf: $result->{spf} (spf: $spf_status, spf_helo: $spf_helo_status)");
$pms->{dmarc_policy} = $result->disposition;
@@ -386,6 +387,18 @@ sub _check_dmarc {
$pms->{dmarc_policy} = 'no policy available';
}
}
+
+ if (defined $pms->{dmarc_result} && $pms->{conf}->{dmarc_save_reports}) {
+ my $rua = eval { $result->published()->rua(); };
+ if (defined $rua && index($rua, 'mailto:') >= 0) {
+ eval { $dmarc->save_aggregate(); };
+ if ($@) {
+ info("report could not be saved: $@");
+ } else {
+ dbg("report will be sent to $rua");
+ }
+ }
+ }
}
sub _check_dmarc_authres {