You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by he...@apache.org on 2019/06/09 16:46:30 UTC

svn commit: r1860912 - in /spamassassin/trunk: MANIFEST UPGRADE lib/Mail/SpamAssassin/Conf.pm lib/Mail/SpamAssassin/Conf/Parser.pm lib/Mail/SpamAssassin/Constants.pm lib/Mail/SpamAssassin/Plugin/Check.pm t/basic_meta2.t

Author: hege
Date: Sun Jun  9 16:46:30 2019
New Revision: 1860912

URL: http://svn.apache.org/viewvc?rev=1860912&view=rev
Log:
Bug 5258 - implement rules_matching() meta expression

Added:
    spamassassin/trunk/t/basic_meta2.t   (with props)
Modified:
    spamassassin/trunk/MANIFEST
    spamassassin/trunk/UPGRADE
    spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm
    spamassassin/trunk/lib/Mail/SpamAssassin/Conf/Parser.pm
    spamassassin/trunk/lib/Mail/SpamAssassin/Constants.pm
    spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Check.pm

Modified: spamassassin/trunk/MANIFEST
URL: http://svn.apache.org/viewvc/spamassassin/trunk/MANIFEST?rev=1860912&r1=1860911&r2=1860912&view=diff
==============================================================================
--- spamassassin/trunk/MANIFEST (original)
+++ spamassassin/trunk/MANIFEST Sun Jun  9 16:46:30 2019
@@ -241,6 +241,7 @@ t/autolearn_force_fail.t
 t/basic_lint.t
 t/basic_lint_without_sandbox.t
 t/basic_meta.t
+t/basic_meta2.t
 t/basic_obj_api.t
 t/bayesbdb.t
 t/bayesdbm.t

Modified: spamassassin/trunk/UPGRADE
URL: http://svn.apache.org/viewvc/spamassassin/trunk/UPGRADE?rev=1860912&r1=1860911&r2=1860912&view=diff
==============================================================================
--- spamassassin/trunk/UPGRADE (original)
+++ spamassassin/trunk/UPGRADE Sun Jun  9 16:46:30 2019
@@ -91,6 +91,8 @@ Note for Users Upgrading to SpamAssassin
 
 - sa-update: New option --httputil to force used download utility
 
+- add rules_matching() expression to meta rules
+
 Note for Users Upgrading to SpamAssassin 3.4.2
 ----------------------------------------------
 

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm?rev=1860912&r1=1860911&r2=1860912&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm Sun Jun  9 16:46:30 2019
@@ -3298,6 +3298,24 @@ count towards the final score unless the
 sub-rules names that start with '__' (two underscores).  SpamAssassin will
 ignore these for scoring.
 
+=item meta SYMBOLIC_TEST_NAME ... rules_matching(RULEGLOB) ...
+
+Special function that will expand to list of matching rulenames.  Can be
+used anywhere in expressions.  Argument supports glob style rulename
+matching (* = anything, ? = one character).  Matching is case-sensitive.
+
+For example, this will hit if atleast two __FOO_* rule hits:
+
+ body __FOO_1  /xxx/
+ body __FOO_2  /yyy/
+ body __FOO_3  /zzz/
+ meta FOO_META  rules_matching(__FOO_*) >= 2
+
+Which would be the same as:
+
+ meta FOO_META  (__FOO_1 + __FOO_2 + __FOO_3) >= 2
+
+
 =cut
 
   push (@cmds, {
@@ -5236,6 +5254,7 @@ sub feature_registryboundaries { 1 } # r
 sub feature_geodb { 1 } # if needed for some reason
 sub feature_dns_block_rule { 1 } # supports 'dns_block_rule' config option
 sub feature_compile_regexp { 1 } # Util::compile_regexp
+sub feature_meta_rules_matching { 1 } # meta rules_matching() expression
 sub perl_min_version_5010000 { return $] >= 5.010000 }  # perl version check ("perl_version" not neatly backwards-compatible)
 
 ###########################################################################

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Conf/Parser.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Conf/Parser.pm?rev=1860912&r1=1860911&r2=1860912&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Conf/Parser.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Conf/Parser.pm Sun Jun  9 16:46:30 2019
@@ -142,8 +142,9 @@ use re 'taint';
 
 our @ISA = qw();
 
-my $RULENAME_RE = RULENAME_RE;
 my $ARITH_EXPRESSION_LEXER = ARITH_EXPRESSION_LEXER;
+my $RULENAME_RE = RULENAME_RE;
+my $META_RULES_MATCHING_RE = META_RULES_MATCHING_RE;
 
 ###########################################################################
 
@@ -1354,6 +1355,9 @@ sub is_meta_valid {
     return 0;
   }
 
+  # Process expandable functions before lexing
+  $rule =~ s/${META_RULES_MATCHING_RE}/ 0 /g;
+
   # Lex the rule into tokens using a rather simple RE method ...
   my @tokens = ($rule =~ /($ARITH_EXPRESSION_LEXER)/og);
   if (length($name) == 1) {

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Constants.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Constants.pm?rev=1860912&r1=1860911&r2=1860912&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Constants.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Constants.pm Sun Jun  9 16:46:30 2019
@@ -44,6 +44,7 @@ BEGIN {
 	MAX_BODY_LINE_LENGTH MAX_HEADER_KEY_LENGTH MAX_HEADER_VALUE_LENGTH
 	MAX_HEADER_LENGTH ARITH_EXPRESSION_LEXER AI_TIME_UNKNOWN
 	CHARSETS_LIKELY_TO_FP_AS_CAPS MAX_URI_LENGTH RULENAME_RE
+	META_RULES_MATCHING_RE
   );
 
   %EXPORT_TAGS = (
@@ -403,4 +404,7 @@ use constant CHARSETS_LIKELY_TO_FP_AS_CA
 # Allowed rulename format
 use constant RULENAME_RE => qr([_a-zA-Z][_a-zA-Z0-9]{0,127});
 
+# meta function rules_matching(), takes argument RULENAME_RE with glob *? characters
+use constant META_RULES_MATCHING_RE => qr/(?<!_)\brules_matching\(\s*([_a-zA-Z*?][_a-zA-Z0-9*?]{0,127})\s*\)/;
+
 1;

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Check.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Check.pm?rev=1860912&r1=1860911&r2=1860912&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Check.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Check.pm Sun Jun  9 16:46:30 2019
@@ -30,6 +30,7 @@ our @ISA = qw(Mail::SpamAssassin::Plugin
 
 my $ARITH_EXPRESSION_LEXER = ARITH_EXPRESSION_LEXER;
 my $RULENAME_RE = RULENAME_RE;
+my $META_RULES_MATCHING_RE = META_RULES_MATCHING_RE;
 
 # methods defined by the compiled ruleset; deleted in finish_tests()
 our @TEMPORARY_METHODS;
@@ -538,6 +539,31 @@ sub do_meta_tests {
   {
     my ($self, $pms, $conf, $rulename, $rule, %opts) = @_;
 
+    # Expand rules_matching() before lexing
+    my $expand_ruleglob = sub {
+      my ($ruleglob) = @_;
+      my $expanded;
+      if (exists $pms->{ruleglob_cache}{$ruleglob}) {
+        $expanded = $pms->{ruleglob_cache}{$ruleglob};
+      } else {
+        my $reglob = $ruleglob;
+        $reglob =~ s/\?/./g;
+        $reglob =~ s/\*/.*?/g;
+        # Glob rules, but do not match ourselves..
+        my @rules = grep {/^${reglob}$/ && $_ ne $rulename} keys %{$conf->{scores}};
+        if (@rules) {
+          $expanded = join('+', sort @rules);
+        } else {
+          $expanded = '0';
+        }
+      }
+      my $logstr = $expanded eq '0' ? 'no matches' : $expanded;
+      dbg("rules: meta $rulename rules_matching($ruleglob) expanded: $logstr");
+      $pms->{ruleglob_cache}{$ruleglob} = $expanded;
+      return " ($expanded) ";
+    };
+    $rule =~ s/${META_RULES_MATCHING_RE}/$expand_ruleglob->($1)/ge;
+
     # Lex the rule into tokens using a rather simple RE method ...
     my @tokens = ($rule =~ /$ARITH_EXPRESSION_LEXER/og);
 

Added: spamassassin/trunk/t/basic_meta2.t
URL: http://svn.apache.org/viewvc/spamassassin/trunk/t/basic_meta2.t?rev=1860912&view=auto
==============================================================================
--- spamassassin/trunk/t/basic_meta2.t (added)
+++ spamassassin/trunk/t/basic_meta2.t Sun Jun  9 16:46:30 2019
@@ -0,0 +1,47 @@
+#!/usr/bin/perl
+
+use lib '.'; 
+use lib 't';
+use SATest; 
+sa_t_init("meta2");
+
+use Test::More;
+plan tests => 5;
+
+# ---------------------------------------------------------------------------
+
+%patterns = (
+
+  q{ TEST_FOO_1 }     => '',
+  q{ TEST_FOO_2 }     => '',
+  q{ TEST_FOO_3 }     => '',
+  q{ TEST_META_1 }     => '',
+
+);
+
+%anti_patterns = (
+
+  q{ TEST_NEG_1 }     => '',
+
+);
+
+tstprefs (qq{
+
+   body __FOO_1 /a/
+   body __FOO_2 /b/
+   body __FOO_33 /c/
+   body __FOO_4 /xyzzynotfound/
+
+   meta TEST_FOO_1 __FOO_1 + __FOO_2 + __FOO_33 + __FOO_4 == 3
+   meta TEST_FOO_2 rules_matching(__FOO_*) == 3
+   meta TEST_FOO_3 __FOO_4 + rules_matching(__FOO_?) == 2
+
+   meta TEST_NEG_1 __FOO_1 + __FOO_2 == 1
+
+   meta TEST_META_1 (TEST_FOO_1 + TEST_FOO_2 + TEST_NEG_1) == 2
+
+});
+
+sarun ("-L -t < data/nice/001 2>&1", \&patterns_run_cb);
+ok_all_patterns();
+

Propchange: spamassassin/trunk/t/basic_meta2.t
------------------------------------------------------------------------------
    svn:executable = *