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 2018/10/28 09:23:36 UTC

svn commit: r1845001 - in /spamassassin/trunk: lib/Mail/SpamAssassin/Conf/Parser.pm t/if_can.t

Author: hege
Date: Sun Oct 28 09:23:36 2018
New Revision: 1845001

URL: http://svn.apache.org/viewvc?rev=1845001&view=rev
Log:
Cache handle_conditional results

Modified:
    spamassassin/trunk/lib/Mail/SpamAssassin/Conf/Parser.pm
    spamassassin/trunk/t/if_can.t

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Conf/Parser.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Conf/Parser.pm?rev=1845001&r1=1845000&r2=1845001&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Conf/Parser.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Conf/Parser.pm Sun Oct 28 09:23:36 2018
@@ -142,6 +142,8 @@ use re 'taint';
 
 our @ISA = qw();
 
+my $ARITH_EXPRESSION_LEXER = ARITH_EXPRESSION_LEXER;
+
 ###########################################################################
 
 sub new {
@@ -237,6 +239,7 @@ sub parse {
   my @conf_lines = split (/\n/, $_[1]);
   my $line;
   $self->{if_stack} = \@if_stack;
+  $self->{cond_cache} = { };
   $self->{file_scoped_attrs} = { };
 
   my $keepmetadata = $conf->{main}->{keep_config_parsing_metadata};
@@ -470,6 +473,7 @@ failed_line:
   }
 
   delete $self->{if_stack};
+  delete $self->{cond_cache};
 
   $self->lint_check();
   $self->fix_tests();
@@ -481,8 +485,21 @@ sub handle_conditional {
   my ($self, $key, $value, $if_stack_ref, $skip_parsing_ref) = @_;
   my $conf = $self->{conf};
 
-  my $lexer = ARITH_EXPRESSION_LEXER;
-  my @tokens = ($value =~ m/($lexer)/og);
+  # If we have already successfully evaled the $value,
+  # just do what we would do then
+  if (exists $self->{cond_cache}{$key.$value}) {
+    push (@{$if_stack_ref}, {
+        type => 'if',
+        conditional => $value,
+        skip_parsing => $$skip_parsing_ref
+      });
+    if ($self->{cond_cache}{$key.$value} == 0) {
+      $$skip_parsing_ref = 1;
+    }
+    return;
+  }
+
+  my @tokens = ($value =~ /($ARITH_EXPRESSION_LEXER)/og);
 
   my $eval = '';
   my $bad = 0;
@@ -541,10 +558,12 @@ sub handle_conditional {
     });
 
   if (eval $eval) {
+    $self->{cond_cache}{$key.$value} = 1;
     # leave $skip_parsing as-is; we may not be parsing anyway in this block.
     # in other words, support nested 'if's and 'require_version's
   } else {
     warn "config: error in $key - $eval: $@" if $@ ne '';
+    $self->{cond_cache}{$key.$value} = 0;
     $$skip_parsing_ref = 1;
   }
 }
@@ -966,8 +985,7 @@ sub _meta_deps_recurse {
   return unless $rule;
 
   # Lex the rule into tokens using a rather simple RE method ...
-  my $lexer = ARITH_EXPRESSION_LEXER;
-  my @tokens = ($rule =~ m/$lexer/og);
+  my @tokens = ($rule =~ /($ARITH_EXPRESSION_LEXER)/og);
 
   # Go through each token in the meta rule
   my $conf_tests = $conf->{tests};
@@ -1287,8 +1305,7 @@ sub is_meta_valid {
   }
 
   # Lex the rule into tokens using a rather simple RE method ...
-  my $lexer = ARITH_EXPRESSION_LEXER;
-  my @tokens = ($rule =~ m/$lexer/og);
+  my @tokens = ($rule =~ /($ARITH_EXPRESSION_LEXER)/og);
   if (length($name) == 1) {
     for (@tokens) {
       print "$name $_\n "  or die "Error writing token: $!";

Modified: spamassassin/trunk/t/if_can.t
URL: http://svn.apache.org/viewvc/spamassassin/trunk/t/if_can.t?rev=1845001&r1=1845000&r2=1845001&view=diff
==============================================================================
--- spamassassin/trunk/t/if_can.t (original)
+++ spamassassin/trunk/t/if_can.t Sun Oct 28 09:23:36 2018
@@ -2,28 +2,32 @@
 
 use lib '.'; use lib 't';
 use SATest; sa_t_init("if_can");
-use Test::More tests => 13;
+use Test::More tests => 17;
 
 # ---------------------------------------------------------------------------
 
 %patterns = (
 
         q{ GTUBE }, 'gtube',
-        q{ SHOULD_BE_CALLED1 }, 'should_be_called1',
-        q{ SHOULD_BE_CALLED2 }, 'should_be_called2',
-        q{ SHOULD_BE_CALLED3 }, 'should_be_called3',
-        q{ SHOULD_BE_CALLED4 }, 'should_be_called4',
-        q{ SHOULD_BE_CALLED5 }, 'should_be_called5',
-        q{ SHOULD_BE_CALLED6 }, 'should_be_called6',
-        q{ SHOULD_BE_CALLED7 }, 'should_be_called7',
+        q{ SHOULD_BE_CALLED01 }, 'should_be_called01',
+        q{ SHOULD_BE_CALLED02 }, 'should_be_called02',
+        q{ SHOULD_BE_CALLED03 }, 'should_be_called03',
+        q{ SHOULD_BE_CALLED04 }, 'should_be_called04',
+        q{ SHOULD_BE_CALLED05 }, 'should_be_called05',
+        q{ SHOULD_BE_CALLED06 }, 'should_be_called06',
+        q{ SHOULD_BE_CALLED07 }, 'should_be_called07',
+        q{ SHOULD_BE_CALLED08 }, 'should_be_called08',
+        q{ SHOULD_BE_CALLED09 }, 'should_be_called09',
+        q{ SHOULD_BE_CALLED10 }, 'should_be_called10',
+        q{ SHOULD_BE_CALLED11 }, 'should_be_called11',
 
 );
 %anti_patterns = (
 
-        q{ SHOULD_NOT_BE_CALLED1 }, 'should_not_be_called1',
-        q{ SHOULD_NOT_BE_CALLED2 }, 'should_not_be_called2',
-        q{ SHOULD_NOT_BE_CALLED3 }, 'should_not_be_called3',
-        q{ SHOULD_NOT_BE_CALLED4 }, 'should_not_be_called4',
+        q{ SHOULD_NOT_BE_CALLED01 }, 'should_not_be_called01',
+        q{ SHOULD_NOT_BE_CALLED02 }, 'should_not_be_called02',
+        q{ SHOULD_NOT_BE_CALLED03 }, 'should_not_be_called03',
+        q{ SHOULD_NOT_BE_CALLED04 }, 'should_not_be_called04',
 
 );
 tstlocalrules (q{
@@ -31,38 +35,51 @@ tstlocalrules (q{
         loadplugin Mail::SpamAssassin::Plugin::Test
 
         if (has(Mail::SpamAssassin::Plugin::Test::check_test_plugin))
-          body SHOULD_BE_CALLED1 /./
+          body SHOULD_BE_CALLED01 /./
         endif
         if (has(Mail::SpamAssassin::Plugin::Test::test_feature_xxxx_true))
-          body SHOULD_BE_CALLED2 /./
+          body SHOULD_BE_CALLED02 /./
         endif
         if (has(Mail::SpamAssassin::Plugin::Test::test_feature_xxxx_false))
-          body SHOULD_BE_CALLED3 /./
+          body SHOULD_BE_CALLED03 /./
         endif
         if (can(Mail::SpamAssassin::Plugin::Test::test_feature_xxxx_true))
-          body SHOULD_BE_CALLED4 /./
+          body SHOULD_BE_CALLED04 /./
         endif
         if (!can(Mail::SpamAssassin::Plugin::Test::test_feature_xxxx_false))
-          body SHOULD_BE_CALLED5 /./
+          body SHOULD_BE_CALLED05 /./
         endif
         if (!has(Mail::SpamAssassin::Plugin::Test::test_feature_xxxx_nosuch))
-          body SHOULD_BE_CALLED6 /./
+          body SHOULD_BE_CALLED06 /./
         endif
         if (!can(Mail::SpamAssassin::Plugin::Test::test_feature_xxxx_nosuch))
-          body SHOULD_BE_CALLED7 /./
+          body SHOULD_BE_CALLED07 /./
+        endif
+        if can(Mail::SpamAssassin::Plugin::Test::test_feature_xxxx_true) && version > 0.00000
+          body SHOULD_BE_CALLED08 /./
+        endif
+        if !can(Mail::SpamAssassin::Plugin::Test::test_feature_xxxx_false  ) && !(! version > 0.00000)
+          body SHOULD_BE_CALLED09 /./
+        endif
+        if has(Mail::SpamAssassin::Plugin::Test::test_feature_xxxx_true) && (!can(Mail::SpamAssassin::Plugin::Test::test_feature_xxxx_nosuch))
+          body SHOULD_BE_CALLED10 /./
         endif
 
         if !has(Mail::SpamAssassin::Plugin::Test::check_test_plugin)
-          body SHOULD_NOT_BE_CALLED1 /./
+          body SHOULD_NOT_BE_CALLED01 /./
         endif
         if (has(Mail::SpamAssassin::Plugin::Test::non_existent_method))
-          body SHOULD_NOT_BE_CALLED2 /./
+          body SHOULD_NOT_BE_CALLED02 /./
         endif
         if (can(Mail::SpamAssassin::Plugin::Test::non_existent_method))
-          body SHOULD_NOT_BE_CALLED3 /./
+          body SHOULD_NOT_BE_CALLED03 /./
         endif
+        if can(Mail::SpamAssassin::Plugin::Test::test_feature_xxxx_true)
         if (can(Mail::SpamAssassin::Plugin::Test::test_feature_xxxx_false))
-          body SHOULD_NOT_BE_CALLED4 /./
+          body SHOULD_NOT_BE_CALLED04 /./
+        else
+          body SHOULD_BE_CALLED11 /./
+        endif
         endif
 
 });