Bug 7208 - URILocalBL fails to load
Summary: URILocalBL fails to load
Status: RESOLVED FIXED
Alias: None
Product: Spamassassin
Classification: Unclassified
Component: Plugins (show other bugs)
Version: 3.4.1
Hardware: PC Linux
: P2 critical
Target Milestone: 3.4.2
Assignee: SpamAssassin Developer Mailing List
URL:
Whiteboard:
Keywords:
: 7332 (view as bug list)
Depends on:
Blocks:
 
Reported: 2015-06-09 13:42 UTC by andrew
Modified: 2018-02-22 03:15 UTC (History)
5 users (show)



Attachment Type Modified Status Actions Submitter/CLA Status

Note You need to log in before you can comment on or make changes to this bug.
Description andrew 2015-06-09 13:42:42 UTC
The URILocalBL plugin does not load. It emits the following error.

Jun  9 15:22:48.009 [2290] dbg: plugin: loading Mail::SpamAssassin::Plugin::URILocalBL from @INC
Jun  9 15:22:48.011 [2290] warn: plugin: failed to parse plugin (from @INC): Type of arg 1 to each must be hash (not hash element) at /usr/share/perl5/vendor_perl/Mail/SpamAssassin/Plugin/URILocalBL.pm line 353, near "}) "
Jun  9 15:22:48.011 [2290] warn: Type of arg 1 to keys must be hash (not hash element) at /usr/share/perl5/vendor_perl/Mail/SpamAssassin/Plugin/URILocalBL.pm line 377, near "})"
Jun  9 15:22:48.011 [2290] warn: Type of arg 1 to keys must be hash (not hash element) at /usr/share/perl5/vendor_perl/Mail/SpamAssassin/Plugin/URILocalBL.pm line 406, near "})"
Jun  9 15:22:48.011 [2290] warn: Compilation failed in require at (eval 107) line 1.
Comment 1 Kevin A. McGrail 2015-06-09 13:48:54 UTC
I believe that is related to a rule not a code issue.

Run spamassassin -D --lint and look for the output from this debug:

dbg("check: uri_local_bl evaluating rule %s\n", $test);
Comment 2 andrew 2015-06-09 13:52:17 UTC
The error occurs during the initialization of the plugins before rules are evaluated.

There are no rules at the moment using that plugin, but given that should a rule or the absence of rules kill the plugin ?
Comment 3 andrew 2015-06-09 13:54:58 UTC
# spamassassin -D --lint 2> debug.txt
# grep uri_local_bl debug.txt

The plugin does not load so the debug will not fire.
Comment 4 Kevin A. McGrail 2015-06-09 14:03:14 UTC
(In reply to andrew from comment #3)
> # spamassassin -D --lint 2> debug.txt
> # grep uri_local_bl debug.txt
> 
> The plugin does not load so the debug will not fire.

Do you have Geo::IP working?

What does spamassassin -D --lint 2>&1 | grep -i URILoca -A5 show?
Comment 5 andrew 2015-06-09 14:14:26 UTC
I do have GeoIP::IP installed and working

Jun  9 15:53:44.776 [3979] dbg: diag: [...] module installed: Geo::IP, version 1.45

The output of "spamassassin -D --lint 2>&1 | grep -i URILoca -A5":

# spamassassin -D --lint 2>&1 | grep -i URILoca -A5
Jun  9 16:11:20.250 [4761] dbg: plugin: loading Mail::SpamAssassin::Plugin::URILocalBL from @INC
Jun  9 16:11:20.252 [4761] warn: plugin: failed to parse plugin (from @INC): Type of arg 1 to each must be hash (not hash element) at /usr/share/perl5/vendor_perl/Mail/SpamAssassin/Plugin/URILocalBL.pm line 353, near "}) "
Jun  9 16:11:20.252 [4761] warn: Type of arg 1 to keys must be hash (not hash element) at /usr/share/perl5/vendor_perl/Mail/SpamAssassin/Plugin/URILocalBL.pm line 377, near "})"
Jun  9 16:11:20.252 [4761] warn: Type of arg 1 to keys must be hash (not hash element) at /usr/share/perl5/vendor_perl/Mail/SpamAssassin/Plugin/URILocalBL.pm line 406, near "})"
Jun  9 16:11:20.252 [4761] warn: Compilation failed in require at (eval 148) line 1.
Jun  9 16:11:20.252 [4761] dbg: plugin: loading Mail::SpamAssassin::Plugin::PDFInfo from @INC
Comment 6 andrew 2015-06-09 16:30:41 UTC
Seems to fail a syntax check as well.

perl -c /usr/share/perl5/vendor_perl/Mail/SpamAssassin/Plugin/URILocalBL.pm
Type of arg 1 to each must be hash (not hash element) at /usr/share/perl5/vendor_perl/Mail/SpamAssassin/Plugin/URILocalBL.pm line 354, near "}) "
Type of arg 1 to keys must be hash (not hash element) at /usr/share/perl5/vendor_perl/Mail/SpamAssassin/Plugin/URILocalBL.pm line 378, near "})"
Type of arg 1 to keys must be hash (not hash element) at /usr/share/perl5/vendor_perl/Mail/SpamAssassin/Plugin/URILocalBL.pm line 407, near "})"
Comment 7 Mark Martinec 2015-06-09 18:33:38 UTC
> Seems to fail a syntax check as well.

Depending on a version of perl, one may get just warnings,
e.g. with 5.22:

warn: each on reference is experimental
  at /usr/local/lib/perl5/site_perl/Mail/SpamAssassin/Plugin/URILocalBL.pm line 353.
warn: keys on reference is experimental
  at /usr/local/lib/perl5/site_perl/Mail/SpamAssassin/Plugin/URILocalBL.pm line 377.
warn: keys on reference is experimental
  at /usr/local/lib/perl5/site_perl/Mail/SpamAssassin/Plugin/URILocalBL.pm line 406.

Don't know if this is a bug or perhaps a new perl feature is taken for granted.
Comment 8 Kevin A. McGrail 2015-06-09 20:11:53 UTC
> Do you have Geo::IP working?

I can recreate the issue, Thanks.  Adding the author to the bug.


Philipp,

Two wide version of perl to show the issue.

In perl 5.17.8, a simple perl -c of URILocalBL.pm passes.

Older perl such as 5.8.6, fails on perl -c with these errors:

Type of arg 1 to each must be hash (not hash element) at /usr/local/lib/perl5/site_perl/5.8.6/Mail/SpamAssassin/Plugin/URILocalBL.pm line 353, near "}) "
Type of arg 1 to keys must be hash (not hash element) at /usr/local/lib/perl5/site_perl/5.8.6/Mail/SpamAssassin/Plugin/URILocalBL.pm line 377, near "})"
Type of arg 1 to keys must be hash (not hash element) at /usr/local/lib/perl5/site_perl/5.8.6/Mail/SpamAssassin/Plugin/URILocalBL.pm line 406, near "})"
/usr/local/lib/perl5/site_perl/5.8.6/Mail/SpamAssassin/Plugin/URILocalBL.pm had compilation errors.

Based on similar descriptions (http://stackoverflow.com/questions/20824920/perl-array-references-and-avoiding-type-of-arg-1-to-keys-must-be-hash-error), I think we need to typecast the hashrefs, i.e.

Index: lib/Mail/SpamAssassin/Plugin/URILocalBL.pm
===================================================================
--- lib/Mail/SpamAssassin/Plugin/URILocalBL.pm  (revision 1682254)
+++ lib/Mail/SpamAssassin/Plugin/URILocalBL.pm  (working copy)
@@ -350,7 +350,7 @@
     # look for W3 links only
     next unless (defined $info->{types}->{a});
 
-    while (my($host, $domain) = each $info->{hosts}) {
+    while (my($host, $domain) = each %{$info->{hosts}}) {
 
       # skip if the domain name was matched
       if (exists $rule->{exclusions} && exists $rule->{exclusions}->{$domain}) {
@@ -374,7 +374,7 @@
         }
 
         if (exists $rule->{countries}) {
-          dbg("check: uri_local_bl countries %s\n", join(' ', sort keys $rule->{countries}));
+          dbg("check: uri_local_bl countries %s\n", join(' ', sort keys %{$rule->{countries}}));
 
           my $cc = $self->{geoip}->country_code_by_addr($ip);
 
@@ -403,7 +403,7 @@
         }
 
         if (exists $rule->{isps}) {
-          dbg("check: uri_local_bl isps %s\n", join(' ', map { '"' . $_ . '"'; } sort keys $rule->{isps}));
+          dbg("check: uri_local_bl isps %s\n", join(' ', map { '"' . $_ . '"'; } sort keys %{$rule->{isps}}));
 
           my $isp = $self->{geoisp}->isp_by_name($ip);


Andrew, can you let me know if that works for you?
Comment 9 andrew 2015-06-10 07:08:43 UTC
Thank you Kevin.

That fixes it, for the record i am on perl v5.10.1 on CentOS 6
Comment 10 Kevin A. McGrail 2015-06-10 12:36:58 UTC
(In reply to andrew from comment #9)
> Thank you Kevin.
> 
> That fixes it, for the record i am on perl v5.10.1 on CentOS 6

Thanks. From http://perldoc.perl.org/functions/keys.html, it started in perl 5.14 and the code as it was, should have had a use 5.014 in it since it requires perl 5.014.  I believe the typecasting is more flexible supporting more perl versions and is the correct solution, then.

"Starting with Perl 5.14, keys can take a scalar EXPR, which must contain a reference to an unblessed hash or array. The argument will be dereferenced automatically. This aspect of keys is considered highly experimental. The exact behaviour may change in a future version of Perl.

        for (keys $hashref) { ... }
        for (keys $obj->get_arrayref) { ... }

To avoid confusing would-be users of your code who are running earlier versions of Perl with mysterious syntax errors, put this sort of thing at the top of your file to signal that your code will work only on Perls of a recent vintage:

        use 5.012;	# so keys/values/each work on arrays
        use 5.014;	# so keys/values/each work on scalars (experimental)"


Committed in trunk and 3.4

 svn commit -m 'Bug 7208 to typecast for keys/each in URILocalBL.pm'
Sending        lib/Mail/SpamAssassin/Plugin/URILocalBL.pm
Transmitting file data .
Committed revision 1684653.

3.4 was accidentally part of en masse commit 1684648 that was a consequence of hitting return to soon ;-)

regards,
KAM
Comment 11 Philip Prindeville 2015-06-10 16:00:52 UTC
(In reply to andrew from comment #9)
> Thank you Kevin.
> 
> That fixes it, for the record i am on perl v5.10.1 on CentOS 6

Beat me to the punch!  I was going to prepare the same patch this morning...
Comment 12 Bill Cole 2016-11-28 17:51:16 UTC
*** Bug 7332 has been marked as a duplicate of this bug. ***
Comment 13 Tom Schulz 2016-11-29 18:05:30 UTC
> *** Bug 7332 has been marked as a duplicate of this bug. ***

But the current latest release does not contain the fix. Hint hint ...
Comment 14 Bill Cole 2018-02-22 03:15:22 UTC
*** Bug 7560 has been marked as a duplicate of this bug. ***