more stuff working with double-layer Conf hashes

git-svn-id: https://svn.apache.org/repos/asf/spamassassin/branches/jm_bug_3852_two_level_configs@567784 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/Mail/SpamAssassin/Conf.pm b/lib/Mail/SpamAssassin/Conf.pm
index fa08cca..824d68e 100644
--- a/lib/Mail/SpamAssassin/Conf.pm
+++ b/lib/Mail/SpamAssassin/Conf.pm
@@ -3219,6 +3219,8 @@
 # create a new config tier for user configuration
 sub push_tier {
   my ($self) = @_;
+  dbg ("config: pushing new tier");
+
   $self->{tiers}->[1] = $self->new_tier();
   $self->{activetier} = $self->{tiers}->[1];
   $self->create_lookup_doublehashes();
@@ -3232,6 +3234,8 @@
 # and delete it once the user is no longer active
 sub pop_tier {
   my ($self) = @_;
+  dbg ("config: popping tier");
+
   %{$self} = ();       # clears the top tier entirely
   $self->{ACTIVETIER} = 0;
 
@@ -3271,15 +3275,11 @@
 sub new_two_tier_hash {
   my ($self, $name, $t0, $t1) = @_;
   if (!defined $t0) {
-    if (!defined $self->{tiers}->[0]->{$name}) {
-      $self->{tiers}->[0]->{$name} = { };
-    }
+    $self->{tiers}->[0]->{$name} ||= { };
     $t0 = $self->{tiers}->[0]->{$name};
   }
   if (!defined $t1) {
-    if (!defined $self->{tiers}->[1]->{$name}) {
-      $self->{tiers}->[1]->{$name} = { };
-    }
+    $self->{tiers}->[1]->{$name} ||= { };
     $t1 = $self->{tiers}->[1]->{$name};
   }
 
@@ -3332,7 +3332,7 @@
 
 sub set_score_set {
   my ($self, $set) = @_;
-  $self->{activetier}->{scoreset_current} = $set;
+  $self->{scoreset_current} = $set;
 
   # use TwoTierHash objects to represent certain hashes; lookups
   # in these "hashes" will fall through correctly to the other tiers.
@@ -3345,7 +3345,7 @@
 
 sub get_score_set {
   my($self) = @_;
-  return $self->{activetier}->{scoreset_current};
+  return $self->{scoreset_current};
 }
 
 sub delete_rule {
diff --git a/lib/Mail/SpamAssassin/Conf/Parser.pm b/lib/Mail/SpamAssassin/Conf/Parser.pm
index e96febf..f2789bc 100644
--- a/lib/Mail/SpamAssassin/Conf/Parser.pm
+++ b/lib/Mail/SpamAssassin/Conf/Parser.pm
@@ -682,12 +682,12 @@
 sub set_template_append {
   my ($conf, $key, $value, $line) = @_;
   if ( $value =~ /^"(.*?)"$/ ) { $value = $1; }
-  $conf->{activetier}->{$key} .= $value."\n";
+  $conf->{$key} .= $value."\n";
 }
 
 sub set_template_clear {
   my ($conf, $key, $value, $line) = @_;
-  $conf->{activetier}->{$key} = '';
+  $conf->{$key} = '';
 }
 
 ###########################################################################
diff --git a/lib/Mail/SpamAssassin/Plugin/Check.pm b/lib/Mail/SpamAssassin/Plugin/Check.pm
index 08e07b0..14db6b9 100644
--- a/lib/Mail/SpamAssassin/Plugin/Check.pm
+++ b/lib/Mail/SpamAssassin/Plugin/Check.pm
@@ -792,34 +792,31 @@
 
 sub do_head_eval_tests {
   my ($self, $pms, $priority) = @_;
-  return unless (defined($pms->{conf}->{head_evals}->{$priority}));
   $self->run_eval_tests ($pms, $Mail::SpamAssassin::Conf::TYPE_HEAD_EVALS,
             'head_evals', '', $priority);
 }
 
 sub do_body_eval_tests {
   my ($self, $pms, $priority, $bodystring) = @_;
-  return unless (defined($pms->{conf}->{body_evals}->{$priority}));
   $self->run_eval_tests ($pms, $Mail::SpamAssassin::Conf::TYPE_BODY_EVALS,
             'body_evals', 'BODY: ', $priority, $bodystring);
 }
 
 sub do_rawbody_eval_tests {
   my ($self, $pms, $priority, $bodystring) = @_;
-  return unless (defined($pms->{conf}->{rawbody_evals}->{$priority}));
   $self->run_eval_tests ($pms, $Mail::SpamAssassin::Conf::TYPE_RAWBODY_EVALS,
             'rawbody_evals', 'RAW: ', $priority, $bodystring);
 }
 
 sub do_full_eval_tests {
   my ($self, $pms, $priority, $fullmsgref) = @_;
-  return unless (defined($pms->{conf}->{full_evals}->{$priority}));
   $self->run_eval_tests($pms, $Mail::SpamAssassin::Conf::TYPE_FULL_EVALS,
             'full_evals', '', $priority, $fullmsgref);
 }
 
 sub run_eval_tests {
-  my ($self, $pms, $testtype, $confhashname, $prepend2desc, $priority, @extraevalargs) = @_;
+  my ($self, $pms, $testtype, $confhashname,
+            $prepend2desc, $priority, @extraevalargs) = @_;
  
   return if $self->{main}->call_plugins("have_shortcircuited",
                                         { permsgstatus => $pms });
diff --git a/lib/Mail/SpamAssassin/Util/TwoTierArray.pm b/lib/Mail/SpamAssassin/Util/TwoTierArray.pm
index 145747b..2346f94 100644
--- a/lib/Mail/SpamAssassin/Util/TwoTierArray.pm
+++ b/lib/Mail/SpamAssassin/Util/TwoTierArray.pm
@@ -31,6 +31,7 @@
 # and all reads from tier 1, and if not found there, tier 0.  In
 # effect tier 1 overrides tier 0.  Note that writes will NEVER affect
 # tier 0; create a new object to modify the contents of that tier.
+# This is different from how TwoTierHash works (which can be written to)
 
 ###########################################################################
 
@@ -48,7 +49,7 @@
 sub STORE {
   my ($self, $i, $v) = @_;
   my $a0size = scalar @{$self->{a0}};
-  if ($i > $a0size) {
+  if ($i >= $a0size) {
     $self->{a1}->[$i - $a0size] = $v;
   } else {
     # a write to the a0 area! we cannot do this!
@@ -59,7 +60,7 @@
 sub FETCH {
   my ($self, $i) = @_;
   my $a0size = scalar @{$self->{a0}};
-  if ($i > $a0size) {
+  if ($i >= $a0size) {
     return $self->{a1}->[$i - $a0size];
   } else {
     return $self->{a0}->[$i];
diff --git a/lib/Mail/SpamAssassin/Util/TwoTierHash.pm b/lib/Mail/SpamAssassin/Util/TwoTierHash.pm
index 8d9f30c..ec43644 100644
--- a/lib/Mail/SpamAssassin/Util/TwoTierHash.pm
+++ b/lib/Mail/SpamAssassin/Util/TwoTierHash.pm
@@ -40,7 +40,7 @@
   my $self = {
     h0 => $h0,
     h1 => $h1,
-    activetier => $h1
+    activetier => $h0
   };
   return bless $self, $class;
 }
diff --git a/t/two_tier_config.t b/t/two_tier_config.t
index 774e61b..fb4480c 100755
--- a/t/two_tier_config.t
+++ b/t/two_tier_config.t
@@ -18,7 +18,7 @@
 
 use lib '.'; use lib 't';
 use SATest; sa_t_init("two_tier_config");
-use Test; BEGIN { plan tests => 12 };
+use Test; BEGIN { plan tests => 33 };
 
 use strict;
 require Mail::SpamAssassin;
@@ -27,6 +27,7 @@
 
 my $sa = create_saobj({'dont_copy_prefs' => 1, post_config_text => q{
 
+  allow_user_rules 1
   header LAST_RCVD_LINE   Received =~ /www.fasttrec.com/
   header MESSAGEID_MATCH  MESSAGEID =~ /fasttrec.com/
   header ENV_FROM         EnvelopeFrom =~ /jm.netnoteinc.com/
@@ -34,13 +35,15 @@
   uri URI_RULE            /WWW.SUPERSITESCENTRAL.COM/i
   body BODY_LINE_WRAP     /making obscene amounts of money from the/
   header RELAYS           X-Spam-Relays-Untrusted =~ / helo=www.fasttrec.com /
-
   required_score 7
   rewrite_header Subject  FOO
   add_header spam Foo Hello
   whitelist_from jm@example.com
   blacklist_from n1@example.com
   score URI_RULE 10
+  redirector_pattern    /^http:\/\/foo.com\/(.*)$/i
+  clear_report_template
+  report Foo
 
 }}); $sa->init(0);
 
@@ -49,7 +52,13 @@
 ok ($sa->{conf}->{headers_spam}->{Foo}, "Hello");
 ok ($sa->{conf}->{whitelist_from}->{'jm@example.com'}, '^jm\@example\.com$');
 ok ($sa->{conf}->{blacklist_from}->{'n1@example.com'}, '^n1\@example\.com$');
+ok grep { $_ eq '^jm\@example\.com$' } values %{$sa->{conf}->{whitelist_from}};
+
 ok ($sa->{conf}->{scores}->{URI_RULE}, 10);
+ok grep { m!http:\\/\\/foo.com\\/! } @{$sa->{conf}->{redirector_patterns}};
+ok !grep { m!http:\\/\\/bar.com\\/! } @{$sa->{conf}->{redirector_patterns}};
+
+ok ($sa->{conf}->{report_template}, "Foo\n");
 
 # ---------------------------------------------------------------------------
 
@@ -63,6 +72,10 @@
   unblacklist_from n1@example.com
   whitelist_from n2@example.com
   score URI_RULE 5
+  redirector_pattern    /^http:\/\/bar.com\/(.*)$/i
+
+  # should append
+  report Bar
 
 }; close OUT or die;
 $sa->read_scoreonly_config("log/localrules.tmp/tier1.cf");
@@ -75,6 +88,10 @@
 ok ($sa->{conf}->{whitelist_from}->{'n2@example.com'}, '^n2\@example\.com$');
 ok ($sa->{conf}->{blacklist_from}->{'n1@example.com'}, undef);
 ok ($sa->{conf}->{scores}->{URI_RULE}, 5);
+ok grep { m!http:\\/\\/foo.com\\/! } @{$sa->{conf}->{redirector_patterns}};
+ok grep { m!http:\\/\\/bar.com\\/! } @{$sa->{conf}->{redirector_patterns}};
+
+ok ($sa->{conf}->{report_template}, "Foo\nBar\n");
 
 # ---------------------------------------------------------------------------
 
@@ -87,6 +104,10 @@
 ok ($sa->{conf}->{blacklist_from}->{'n1@example.com'}, '^n1\@example\.com$');
 ok ($sa->{conf}->{blacklist_from}->{'n2@example.com'}, undef);
 ok ($sa->{conf}->{scores}->{URI_RULE}, 10);
+ok grep { m!http:\\/\\/foo.com\\/! } @{$sa->{conf}->{redirector_patterns}};
+ok !grep { m!http:\\/\\/bar.com\\/! } @{$sa->{conf}->{redirector_patterns}};
+
+ok ($sa->{conf}->{report_template}, "Foo\n");
 
 # ---------------------------------------------------------------------------