diff -ur a/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/Dns.pm b/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/Dns.pm --- a/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/Dns.pm 2010-03-16 10:49:21.000000000 -0400 +++ b/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/Dns.pm 2010-07-20 15:54:23.000000000 -0400 @@ -754,7 +754,7 @@ dbg("dns: entering helper-app run mode"); $self->{old_slash} = $/; # Razor pollutes this %{$self->{old_env}} = (); - if ( defined %ENV ) { + if ( %ENV ) { # undefined values in %ENV can result due to autovivification elsewhere, # this prevents later possible warnings when we restore %ENV while (my ($key, $value) = each %ENV) { Only in b/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin: Dns.pm~ diff -ur a/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/HTML.pm b/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/HTML.pm --- a/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/HTML.pm 2010-03-16 10:49:21.000000000 -0400 +++ b/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/HTML.pm 2010-07-20 15:52:50.000000000 -0400 @@ -191,7 +191,7 @@ my $self = shift; my %options = @_; - return join('', @{ $self->{text} }) unless keys %options; + return join('', @{ $self->{text} }) unless %options; my $mask; while (my ($k, $v) = each %options) { Only in b/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin: HTML.pm~ diff -ur a/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/Plugin/BodyEval.pm b/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/Plugin/BodyEval.pm --- a/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/Plugin/BodyEval.pm 2010-03-16 10:49:21.000000000 -0400 +++ b/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/Plugin/BodyEval.pm 2010-07-20 16:04:57.000000000 -0400 @@ -119,7 +119,7 @@ } # If there are no words, mark if there's at least 1 image ... - if (keys %html == 0 && exists $pms->{html}{inside}{img}) { + if (!%html && exists $pms->{html}{inside}{img}) { # Use "\n" as the mark since it can't ever occur normally $html{"\n"}=1; } Only in b/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/Plugin: BodyEval.pm~ Only in b/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/Plugin: check.patch diff -ur a/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/Plugin/Check.pm b/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/Plugin/Check.pm --- a/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/Plugin/Check.pm 2010-03-16 10:49:21.000000000 -0400 +++ b/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/Plugin/Check.pm 2010-07-20 16:03:00.000000000 -0400 @@ -307,64 +307,51 @@ my $package_name = __PACKAGE__; my $methodname = $package_name."::_".$ruletype."_tests_".$clean_priority; - if (defined &{$methodname} && !$doing_user_rules) { -run_compiled_method: - # dbg("rules: run_generic_tests - calling %s", $methodname); - my $t = Mail::SpamAssassin::Timeout->new({ deadline => $master_deadline }); - my $err = $t->run(sub { - no strict "refs"; - $methodname->($pms, @{$opts{args}}); - }); - if ($t->timed_out() && $master_deadline && time > $master_deadline) { - info("check: exceeded time limit in $methodname, skipping further tests"); - $pms->{deadline_exceeded} = 1; - } - return; - } + if (!defined &{$methodname} || $doing_user_rules) { - # use %nopts for named parameter-passing; it's more friendly to future-proof - # subclassing, since new parameters can be added without breaking third-party - # subclassed implementations of this plugin. - my %nopts = ( - ruletype => $ruletype, - doing_user_rules => $doing_user_rules, - priority => $priority, - clean_priority => $clean_priority - ); - - # build up the eval string... - $self->{evalstr_methodname} = $methodname; - $self->{evalstr_chunk_current_methodname} = undef; - $self->{evalstr_chunk_methodnames} = []; - $self->{evalstr_chunk_prefix} = []; # stack (array) of source code sections - $self->{evalstr} = ''; $self->{evalstr_l} = 0; - $self->{evalstr2} = ''; - $self->begin_evalstr_chunk($pms); - - $self->push_evalstr_prefix($pms, ' - # start_rules_plugin_code '.$ruletype.' '.$priority.' - my $scoresptr = $self->{conf}->{scores}; - '); - if (defined $opts{pre_loop_body}) { - $opts{pre_loop_body}->($self, $pms, $conf, %nopts); - } - $self->add_evalstr($pms, - $self->start_rules_plugin_code($ruletype, $priority) ); - while (my($rulename, $test) = each %{$opts{testhash}->{$priority}}) { - $opts{loop_body}->($self, $pms, $conf, $rulename, $test, %nopts); - } - if (defined $opts{post_loop_body}) { - $opts{post_loop_body}->($self, $pms, $conf, %nopts); - } + # use %nopts for named parameter-passing; it's more friendly + # to future-proof subclassing, since new parameters can be added without + # breaking third-party subclassed implementations of this plugin. + my %nopts = ( + ruletype => $ruletype, + doing_user_rules => $doing_user_rules, + priority => $priority, + clean_priority => $clean_priority + ); + + # build up the eval string... + $self->{evalstr_methodname} = $methodname; + $self->{evalstr_chunk_current_methodname} = undef; + $self->{evalstr_chunk_methodnames} = []; + $self->{evalstr_chunk_prefix} = []; # stack (array) of source code sections + $self->{evalstr} = ''; $self->{evalstr_l} = 0; + $self->{evalstr2} = ''; + $self->begin_evalstr_chunk($pms); + + $self->push_evalstr_prefix($pms, ' + # start_rules_plugin_code '.$ruletype.' '.$priority.' + my $scoresptr = $self->{conf}->{scores}; + '); + if (defined $opts{pre_loop_body}) { + $opts{pre_loop_body}->($self, $pms, $conf, %nopts); + } + $self->add_evalstr($pms, + $self->start_rules_plugin_code($ruletype, $priority) ); + while (my($rulename, $test) = each %{$opts{testhash}->{$priority}}) { + $opts{loop_body}->($self, $pms, $conf, $rulename, $test, %nopts); + } + if (defined $opts{post_loop_body}) { + $opts{post_loop_body}->($self, $pms, $conf, %nopts); + } - $self->flush_evalstr($pms, 'run_generic_tests'); - $self->free_ruleset_source($pms, $ruletype, $priority); + $self->flush_evalstr($pms, 'run_generic_tests'); + $self->free_ruleset_source($pms, $ruletype, $priority); - # clear out a previous version of this method - undef &{$methodname}; + # clear out a previous version of this method + undef &{$methodname}; - # generate the loop that goes through each line... - my $evalstr = <<"EOT"; + # generate the loop that goes through each line... + my $evalstr = <<"EOT"; { package $package_name; @@ -373,40 +360,51 @@ sub $methodname { EOT - for my $chunk_methodname (@{$self->{evalstr_chunk_methodnames}}) { - $evalstr .= " $chunk_methodname(\@_);\n"; - } + for my $chunk_methodname (@{$self->{evalstr_chunk_methodnames}}) { + $evalstr .= " $chunk_methodname(\@_);\n"; + } - $evalstr .= <<"EOT"; + $evalstr .= <<"EOT"; } 1; } EOT - delete $self->{evalstr}; # free up some RAM before we eval() - delete $self->{evalstr2}; - delete $self->{evalstr_methodname}; - delete $self->{evalstr_chunk_current_methodname}; - delete $self->{evalstr_chunk_methodnames}; - delete $self->{evalstr_chunk_prefix}; - - dbg("rules: run_generic_tests - compiling eval code: %s, priority %s", - $ruletype, $priority); -# dbg("rules: eval code to compile: $evalstr"); - my $eval_result; - { my $timer = $self->{main}->time_method('compile_gen'); - $eval_result = eval($evalstr); - } - if (!$eval_result) { - my $eval_stat = $@ ne '' ? $@ : "errno=$!"; chomp $eval_stat; - warn "rules: failed to compile $ruletype tests, skipping:\n". - "\t($eval_stat)\n"; - $pms->{rule_errors}++; - } - else { + delete $self->{evalstr}; # free up some RAM before we eval() + delete $self->{evalstr2}; + delete $self->{evalstr_methodname}; + delete $self->{evalstr_chunk_current_methodname}; + delete $self->{evalstr_chunk_methodnames}; + delete $self->{evalstr_chunk_prefix}; + + dbg("rules: run_generic_tests - compiling eval code: %s, priority %s", + $ruletype, $priority); + # dbg("rules: eval code to compile: $evalstr"); + my $eval_result; + { my $timer = $self->{main}->time_method('compile_gen'); + $eval_result = eval($evalstr); + } + if (!$eval_result) { + my $eval_stat = $@ ne '' ? $@ : "errno=$!"; chomp $eval_stat; + warn "rules: failed to compile $ruletype tests, skipping:\n". + "\t($eval_stat)\n"; + $pms->{rule_errors}++; + return; + } dbg("rules: compiled $ruletype tests"); - goto run_compiled_method; + } + +#run_compiled_method: +# dbg("rules: run_generic_tests - calling %s", $methodname); + my $t = Mail::SpamAssassin::Timeout->new({ deadline => $master_deadline }); + my $err = $t->run(sub { + no strict "refs"; + $methodname->($pms, @{$opts{args}}); + }); + if ($t->timed_out() && $master_deadline && time > $master_deadline) { + info("check: exceeded time limit in $methodname, skipping further tests"); + $pms->{deadline_exceeded} = 1; } } diff -ur a/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/Plugin/MIMEEval.pm b/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/Plugin/MIMEEval.pm --- a/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/Plugin/MIMEEval.pm 2010-03-16 10:49:21.000000000 -0400 +++ b/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/Plugin/MIMEEval.pm 2010-07-20 16:06:47.000000000 -0400 @@ -498,7 +498,7 @@ # perhaps just limit to test, and image? next if ($ctype eq 'application/ics'); - my $cte = lc $p->get_header('content-transfer-encoding') || ''; + my $cte = lc($p->get_header('content-transfer-encoding') || ''); next if ($cte !~ /^base64$/); foreach my $l ( @{$p->raw()} ) { my $len = length $l; Only in b/Mail-SpamAssassin-3.3.1/lib/Mail/SpamAssassin/Plugin: MIMEEval.pm~