patch-src::MultiCaseSensHeadersCheck-3.1.0.patch by Victor Ustugov diff -urN lib.orig/Mail/SpamAssassin/Message/Node.pm lib/Mail/SpamAssassin/Message/Node.pm --- lib.orig/Mail/SpamAssassin/Message/Node.pm 2005-08-12 03:38:46.000000000 +0300 +++ lib/Mail/SpamAssassin/Message/Node.pm 2005-09-16 12:48:44.000000000 +0300 @@ -56,6 +56,8 @@ my $self = { headers => {}, raw_headers => {}, + headers_case => {}, + raw_headers_case => {}, body_parts => [], header_order => [] }; @@ -178,6 +180,13 @@ push @{ $self->{'headers'}->{$key} }, _decode_header($raw_value); push @{ $self->{'raw_headers'}->{$key} }, $raw_value; + if ( !exists $self->{'headers_case'}->{$rawkey} ) { + $self->{'headers_case'}->{$rawkey} = []; + $self->{'raw_headers_case'}->{$rawkey} = []; + } + + push @{ $self->{'headers_case'}->{$rawkey} }, _decode_header($raw_value); + push @{ $self->{'raw_headers_case'}->{$rawkey} }, $raw_value; return $self->{'headers'}->{$key}->[-1]; } @@ -191,6 +200,28 @@ } } +sub header_case { + my $self = shift; + my $rawkey = shift; + + return unless ( defined $rawkey ); + + my $key = $rawkey; + + # Trim whitespace off of the header keys + $key =~ s/^\s+//; + $key =~ s/\s+$//; + + if (wantarray) { + return unless exists $self->{'headers_case'}->{$key}; + return @{ $self->{'headers_case'}->{$key} }; + } + else { + return '' unless exists $self->{'headers_case'}->{$key}; + return $self->{'headers_case'}->{$key}->[-1]; + } +} + =item raw_header() Retrieves the raw version of headers from a specific MIME part. The only @@ -226,6 +257,24 @@ } } +sub raw_header_case { + my $self = shift; + my $key = shift; + + # Trim whitespace off of the header keys + $key =~ s/^\s+//; + $key =~ s/\s+$//; + + if (wantarray) { + return unless exists $self->{'raw_headers_case'}->{$key}; + return @{ $self->{'raw_headers_case'}->{$key} }; + } + else { + return '' unless exists $self->{'raw_headers_case'}->{$key}; + return $self->{'raw_headers_case'}->{$key}->[-1]; + } +} + =item add_body_part() Adds a Node child object to the current node object. @@ -466,6 +515,8 @@ foreach ( grep(/^${hdr}$/i, keys %{$self->{'headers'}}) ) { delete $self->{'headers'}->{$_}; delete $self->{'raw_headers'}->{$_}; + delete $self->{'headers_case'}->{$_}; + delete $self->{'raw_headers_case'}->{$_}; } my @neworder = grep(!/^${hdr}$/i, @{$self->{'header_order'}}); @@ -566,6 +617,35 @@ } } +sub get_header_case { + my ($self, $hdr, $raw) = @_; + $raw ||= 0; + + # And now pick up all the entries into a list + # This is assumed to include a newline at the end ... + # This is also assumed to have removed continuation bits ... + + # Deal with the possibility that header() or raw_header() returns undef + my @hdrs; + if ( $raw ) { + if (@hdrs = $self->raw_header_case($hdr)) { + @hdrs = map { s/\r?\n\s+/ /g; $_; } @hdrs; + } + } + else { + if (@hdrs = $self->header_case($hdr)) { + @hdrs = map { "$_\n" } @hdrs; + } + } + + if (wantarray) { + return @hdrs; + } + else { + return @hdrs ? $hdrs[-1] : undef; + } +} + =item get_all_headers() Retrieve all headers. Each header will have a newline at the end and @@ -635,6 +715,8 @@ # Clean up ourself undef $self->{'headers'}; undef $self->{'raw_headers'}; + undef $self->{'headers_case'}; + undef $self->{'raw_headers_case'}; undef $self->{'header_order'}; undef $self->{'raw'}; undef $self->{'decoded'}; diff -urN lib.orig/Mail/SpamAssassin/PerMsgStatus.pm lib/Mail/SpamAssassin/PerMsgStatus.pm --- lib.orig/Mail/SpamAssassin/PerMsgStatus.pm 2005-09-16 12:16:34.000000000 +0300 +++ lib/Mail/SpamAssassin/PerMsgStatus.pm 2005-09-16 13:40:11.000000000 +0300 @@ -1446,16 +1446,33 @@ sub _get { my ($self, $request) = @_; + if ($request =~ /\|/) { + my($res); + foreach my $subrequest (split(/\|/, $request)) { + my $getcase = ($subrequest =~ s/:case//); + my $getraw = ($subrequest eq 'ALL' || $subrequest =~ s/:raw$//); + if ($getcase) { + $res .= '|'.join ("\n", $self->{msg}->get_header_case($subrequest, $getraw)); + } else { + $res .= '|'.join ("\n", $self->{msg}->get_header($subrequest, $getraw)); + } + } + $res =~ s/^\|//; + return($res); + } + my $result; my $getaddr = 0; my $getname = 0; my $getraw = 0; + my $getcase = 0; # special queries if (index($request, ':') != -1) { $getaddr = ($request =~ s/:addr$//); $getname = ($request =~ s/:name$//); $getraw = ($request =~ s/:raw$//); + $getcase = ($request =~ s/:case//); } # ALL: entire raw headers @@ -1495,7 +1512,11 @@ } # a conventional header else { - $result = join('', $self->{msg}->get_header($request, $getraw)); + if ($getcase) { + $result = join('', $self->{msg}->get_header_case($request, $getraw)); + } else { + $result = join('', $self->{msg}->get_header($request, $getraw)); + } # metadata if (!$result) {