--- Mail/SpamAssassin/AsyncLoop.pm~ 2011-06-07 01:59:17.000000000 +0200 +++ Mail/SpamAssassin/AsyncLoop.pm 2013-05-29 01:37:58.000000000 +0200 @@ -361,5 +361,12 @@ $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 @@ -449,5 +456,6 @@ 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}, --- Mail/SpamAssassin/Conf/Parser.pm~ 2011-06-07 01:59:17.000000000 +0200 +++ Mail/SpamAssassin/Conf/Parser.pm 2013-05-29 01:32:06.000000000 +0200 @@ -1249,5 +1249,5 @@ my $mods = ''; local ($1,$2); - if ($re =~ s/^m{//) { + if ($re =~ s/^m\{//) { $re =~ s/}([a-z]*)$//; $mods = $1; } --- Mail/SpamAssassin/DnsResolver.pm~ 2011-06-07 01:59:17.000000000 +0200 +++ Mail/SpamAssassin/DnsResolver.pm 2013-05-29 01:32:06.000000000 +0200 @@ -441,8 +441,14 @@ 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; } --- Mail/SpamAssassin/Message.pm~ 2011-06-07 01:59:17.000000000 +0200 +++ Mail/SpamAssassin/Message.pm 2013-05-29 01:32:06.000000000 +0200 @@ -567,5 +567,5 @@ # 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: $!"; } --- Mail/SpamAssassin/PerMsgStatus.pm~ 2011-06-07 01:59:17.000000000 +0200 +++ Mail/SpamAssassin/PerMsgStatus.pm 2013-05-29 01:32:06.000000000 +0200 @@ -421,6 +421,6 @@ } - # 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 @@ -1253,11 +1253,10 @@ 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'; }, --- Mail/SpamAssassin/Util.pm~ 2013-05-29 01:29:59.000000000 +0200 +++ Mail/SpamAssassin/Util.pm 2013-05-29 01:33:16.000000000 +0200 @@ -1588,5 +1588,5 @@ return undef; # invalid } - elsif ($re =~ s/^m{//) { # m{foo/bar} + elsif ($re =~ s/^m\{//) { # m{foo/bar} $delim = '}'; }