> caution: that's quite a lot of speculation.
 
Yup.
 
Then again, I get paid specifically for making those kinds of speculations and being right about them a goodly percentage of the time, even in code I'm not familiar with.
 
I'll stand behind my workaround being functional until proven otherwise.
 
I'll also at least stand beside my contention that the root problem is a perl bug (or 'feature' which *I* would consider a bug, even if the Perl folks don't).
 
BTW, I note that this problem shows that the OP has allow_user_rules turned on, since this is failing on the same eval that fails here a lot of the time on an entirely different kind of system.
 
This should actually be fairly easy to fix.  The following modified code probably won't work since I don't know Perl, but the concepts should be obvious enough to fix up and make work:
 
PMS Line 1903..1955:
 
  # otherwise build up the eval string...
  my $evalstr = '';
  my $evalstr2 = '';
  my $rulegroup = 1;
  my $rulecount = 0;
 
  while (my($rulename, $pat) = each %{$self->{conf}{uri_tests}->{$priority}}) {
    $evalstr .= '
      if ($self->{conf}->{scores}->{q{'.$rulename.'}}) {
        '.$rulename.'_uri_test($self, @_); # call procedurally for speed
      }
    ';
    $rulecount = $rulecount + 1;
# assume we can do 100 rules per group until we know better.
if ($rulecount == 100) {
    $rulegroup = $rulegroup + 1;
    $rulecount = 0;
    $evalstr .= '}
    sub _body_uri_tests'.$rulegroup.'_$clean_priority {
    ';
}
 
    if ($doing_user_rules) {
      next if (!$self->is_user_rule_sub ($rulename.'_uri_test'));
    }
 
    $evalstr2 .= '
    sub '.$rulename.'_uri_test {
       my $self = shift;
       foreach (@_) {
         '.$self->hash_line_for_rule($rulename).'
         if ('.$pat.') {
            $self->got_pattern_hit (q{'.$rulename.'}, "URI: ");
            '. $self->ran_rule_debug_code ($rulename,"uri test", 4) . '
            # Ok, we hit, stop now.
            last;
         }
       }
    }
    ';
  }
 
  # clear out a previous version of this fn, if already defined
  if (defined &{'_body_uri_tests_'.$clean_priority}) {
    undef &{'_body_uri_tests_'.$clean_priority};
  }
 
  return unless ($evalstr);
 
    $evalstr =   'sub _body_uri_tests1_$clean_priority {
    '.$evalstr.'
}';
 
  # generate the loop that goes through each line...
  $evalstr = <<"EOT";
{
  package Mail::SpamAssassin::PerMsgStatus;
 
  $evalstr2
  $evalstr
 
  sub _body_uri_tests_$clean_priority {
    my \$self = shift;
EOT
    $rulecount = 1;
    while ($rulecount <= $rulegroup) {
        $evalstr .= _body_uri_tests'.$rulecount.'$clean_priority($self, @_);
';
    $evalstr .= '
  }
 
  1;
}
';
 

------------
 
BTW, I'd be interested in what that code looked like in actual Perl rather than my guess of what it would look like.  :-)
 
        Loren
 

Reply via email to