diff -Nur Mail-SpamAssassin-3.3.2.orig/lib/Mail/SpamAssassin/AsyncLoop.pm Mail-SpamAssassin-3.3.2/lib/Mail/SpamAssassin/AsyncLoop.pm --- Mail-SpamAssassin-3.3.2.orig/lib/Mail/SpamAssassin/AsyncLoop.pm 2011-06-06 17:59:17.000000000 -0600 +++ Mail-SpamAssassin-3.3.2/lib/Mail/SpamAssassin/AsyncLoop.pm 2014-01-04 12:06:42.841484361 -0700 @@ -360,7 +360,15 @@ } $now = time; # capture new timestamp, after possible sleep in 'select' - while (my($key,$ent) = each %$pending) { + # A callback routine may generate another DNS query, which may insert + # an entry into the %$pending hash thus invalidating the each() context. + # So, make sure that callbacks are not called while the each() context + # is open, or avoid using each(). [Bug 6937] + # + # while (my($key,$ent) = each %$pending) { + foreach my $key (keys %$pending) { + my $ent = $pending->{$key}; + my $id = $ent->{id}; if (defined $ent->{poll_callback}) { # call a "poll_callback" if exists # be nice, provide fresh info to a callback routine @@ -448,7 +456,8 @@ my $pending = $self->{pending_lookups}; my $foundcnt = 0; my $now = time; - while (my($key,$ent) = each %$pending) { + foreach my $key (keys %$pending) { + my $ent = $pending->{$key}; dbg("async: aborting after %.3f s, %s: %s", $now - $ent->{start_time}, (defined $ent->{timeout_initial} && diff -Nur Mail-SpamAssassin-3.3.2.orig/lib/Mail/SpamAssassin/Conf/Parser.pm Mail-SpamAssassin-3.3.2/lib/Mail/SpamAssassin/Conf/Parser.pm --- Mail-SpamAssassin-3.3.2.orig/lib/Mail/SpamAssassin/Conf/Parser.pm 2011-06-06 17:59:17.000000000 -0600 +++ Mail-SpamAssassin-3.3.2/lib/Mail/SpamAssassin/Conf/Parser.pm 2014-01-04 12:07:42.897360312 -0700 @@ -1248,7 +1248,7 @@ my $safere = $re; my $mods = ''; local ($1,$2); - if ($re =~ s/^m{//) { + if ($re =~ s/^m\{//) { $re =~ s/}([a-z]*)$//; $mods = $1; } elsif ($re =~ s/^m\(//) { diff -Nur Mail-SpamAssassin-3.3.2.orig/lib/Mail/SpamAssassin/DnsResolver.pm Mail-SpamAssassin-3.3.2/lib/Mail/SpamAssassin/DnsResolver.pm --- Mail-SpamAssassin-3.3.2.orig/lib/Mail/SpamAssassin/DnsResolver.pm 2011-06-06 17:59:17.000000000 -0600 +++ Mail-SpamAssassin-3.3.2/lib/Mail/SpamAssassin/DnsResolver.pm 2014-01-04 12:09:17.797584164 -0700 @@ -440,10 +440,16 @@ { my $timer; # collects timestamp when variable goes out of scope if (!defined($timeout) || $timeout > 0) { $timer = $self->{main}->time_method("poll_dns_idle") } + $! = 0; ($nfound, $timeleft) = select($rout=$rin, undef, undef, $timeout); } if (!defined $nfound || $nfound < 0) { - warn "dns: select failed: $!"; + if ($!) { warn "dns: select failed: $!\n" } + else { info("dns: select interrupted") } + return; + } elsif (!$nfound) { + if (!defined $timeout) { warn("dns: select returned empty-handed\n") } + elsif ($timeout > 0) { dbg("dns: select timed out %.3f s", $timeout) } return; } diff -Nur Mail-SpamAssassin-3.3.2.orig/lib/Mail/SpamAssassin/Message.pm Mail-SpamAssassin-3.3.2/lib/Mail/SpamAssassin/Message.pm --- Mail-SpamAssassin-3.3.2.orig/lib/Mail/SpamAssassin/Message.pm 2011-06-06 17:59:17.000000000 -0600 +++ Mail-SpamAssassin-3.3.2/lib/Mail/SpamAssassin/Message.pm 2014-01-04 12:10:02.247752269 -0700 @@ -566,7 +566,7 @@ while (my $part = shift @toclean) { # bug 5557: windows requires tmp file be closed before it can be rm'd if (ref $part->{'raw'} eq 'GLOB') { - close($part->{'raw'}) or die "error closing input file: $!"; + close($part->{'raw'}) or warn "error closing input file: $!"; } # bug 5858: avoid memory leak with deep MIME structure diff -Nur Mail-SpamAssassin-3.3.2.orig/lib/Mail/SpamAssassin/PerMsgStatus.pm Mail-SpamAssassin-3.3.2/lib/Mail/SpamAssassin/PerMsgStatus.pm --- Mail-SpamAssassin-3.3.2.orig/lib/Mail/SpamAssassin/PerMsgStatus.pm 2011-06-06 17:59:17.000000000 -0600 +++ Mail-SpamAssassin-3.3.2/lib/Mail/SpamAssassin/PerMsgStatus.pm 2014-01-04 12:12:03.585481321 -0700 @@ -420,8 +420,8 @@ } } - # ignore tests with 0 score in this scoreset - next if ($scores->{$test} == 0); + # ignore tests with 0 score (or undefined) in this scoreset + next if !$scores->{$test}; # Go ahead and add points to the proper locations if (!$self->{conf}->maybe_header_only ($test)) { @@ -1252,13 +1252,12 @@ my $arg = (shift || ","); my $line = ''; foreach my $test (sort @{$self->{test_names_hit}}) { - if (!$line) { - $line .= $test . "=" . $self->{conf}->{scores}->{$test}; - } else { - $line .= $arg . $test . "=" . $self->{conf}->{scores}->{$test}; - } + my $score = $self->{conf}->{scores}->{$test}; + $score = '0' if !defined $score; + $line .= $arg if $line ne ''; + $line .= $test . "=" . $score; } - $line ? $line : 'none'; + $line ne '' ? $line : 'none'; }, PREVIEW => sub { $self->get_content_preview() }, diff -Nur Mail-SpamAssassin-3.3.2.orig/lib/Mail/SpamAssassin/Util.pm Mail-SpamAssassin-3.3.2/lib/Mail/SpamAssassin/Util.pm --- Mail-SpamAssassin-3.3.2.orig/lib/Mail/SpamAssassin/Util.pm 2011-06-06 17:59:17.000000000 -0600 +++ Mail-SpamAssassin-3.3.2/lib/Mail/SpamAssassin/Util.pm 2014-01-04 12:12:26.262056907 -0700 @@ -1585,7 +1585,7 @@ elsif ($re =~ s/^m{//) { # m{foo/bar} $delim = '}'; } - elsif ($re =~ s/^m\(//) { # m(foo/bar) + elsif ($re =~ s/^m\{//) { # m{foo/bar} $delim = ')'; } elsif ($re =~ s/^m