> 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 $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
}
';
$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'));
}
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;
}
}
}
';
}
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};
}
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;
$evalstr = <<"EOT";
{
package Mail::SpamAssassin::PerMsgStatus;
$evalstr2
$evalstr
sub _body_uri_tests_$clean_priority {
my \$self = shift;
EOT
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