patch-src::MultiCaseSensHeadersCheck-3.2.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 2007-05-01 16:54:08.000000000 +0300 +++ lib/Mail/SpamAssassin/Message/Node.pm 2007-05-19 19:37:28.000000000 +0300 @@ -56,6 +56,8 @@ my $self = { headers => {}, raw_headers => {}, + headers_case => {}, + raw_headers_case => {}, header_order => [] }; @@ -178,6 +180,13 @@ 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} }, $self->_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. @@ -546,6 +595,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'}}); @@ -645,6 +696,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 diff -urN lib.orig/Mail/SpamAssassin/PerMsgStatus.pm lib/Mail/SpamAssassin/PerMsgStatus.pm --- lib.orig/Mail/SpamAssassin/PerMsgStatus.pm 2007-05-01 16:54:10.000000000 +0300 +++ lib/Mail/SpamAssassin/PerMsgStatus.pm 2007-05-19 13:41:01.000000000 +0300 @@ -1519,21 +1519,39 @@ 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 if ($request eq 'ALL') { - $result = $self->{msg}->get_all_headers(1); +# $result = $self->{msg}->get_all_headers(1); + $result = ($getraw ? $self->{msg}->get_pristine_header("") : $self->{msg}->get_all_headers(1)); } # ALL-TRUSTED: entire trusted raw headers elsif ($request eq 'ALL-TRUSTED') { @@ -1601,9 +1619,18 @@ } # a conventional header else { - if ($getraw) { +# if ($getraw) { +# $result = join('', $self->{msg}->raw_header($request)); +# } else { +# $result = join('', $self->{msg}->get_header($request)); +# } + if ($getcase and $getraw) { + $result = join('', $self->{msg}->raw_header_case($request)); + } elsif ($getcase and !$getraw) { + $result = join('', $self->{msg}->get_header_case($request)); + } elsif (!$getcase and $getraw) { $result = join('', $self->{msg}->raw_header($request)); - } else { + } elsif (!$getcase and !$getraw) { $result = join('', $self->{msg}->get_header($request)); }