You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by fe...@apache.org on 2005/06/05 21:06:26 UTC
svn commit: r180131 -
/spamassassin/branches/3.0/lib/Mail/SpamAssassin/Message.pm
Author: felicity
Date: Sun Jun 5 12:06:24 2005
New Revision: 180131
URL: http://svn.apache.org/viewcvs?rev=180131&view=rev
Log:
bug 4171: new way of determining header/body separation w/out needing to look for MIME boundary.
Modified:
spamassassin/branches/3.0/lib/Mail/SpamAssassin/Message.pm
Modified: spamassassin/branches/3.0/lib/Mail/SpamAssassin/Message.pm
URL: http://svn.apache.org/viewcvs/spamassassin/branches/3.0/lib/Mail/SpamAssassin/Message.pm?rev=180131&r1=180130&r2=180131&view=diff
==============================================================================
--- spamassassin/branches/3.0/lib/Mail/SpamAssassin/Message.pm (original)
+++ spamassassin/branches/3.0/lib/Mail/SpamAssassin/Message.pm Sun Jun 5 12:06:24 2005
@@ -122,7 +122,6 @@
# Go through all the headers of the message
my $header = '';
- my $boundary;
while ( my $last = shift @message ) {
if ( $last =~ /^From\s/ ) {
# mbox formated mailbox
@@ -157,72 +156,63 @@
}
# Store the non-modified headers in a scalar
- $self->{'pristine_headers'} .= $last;
+ unless ($self->{'missing_head_body_separator'}) {
+ $self->{'pristine_headers'} .= $last;
+ }
# NB: Really need to figure out special folding rules here!
if ( $last =~ /^[ \t]+/ ) { # if its a continuation
if ($header) {
$header .= $last; # fold continuations
-
- # If we're currently dealing with a content-type header, and there's a
- # boundary defined, use it. Since there could be multiple
- # content-type headers in a message, the last one will be the one we
- # should use, so just keep updating as they come in.
- if ($header =~ /^content-type:\s*(\S.*)$/is) {
- my($type,$temp_boundary) = Mail::SpamAssassin::Util::parse_content_type($1);
- $boundary = $temp_boundary if ($type =~ /^multipart/ && defined $temp_boundary);
- }
-
- # Go onto the next header line, unless the next line is a
- # multipart mime boundary, where we know we're going to stop
- # below, so drop through for final header processing.
- next unless (defined $boundary && @message && $message[0] =~ /^--\Q$boundary\E(?:--|\s*$)/);
- }
- else {
- # There was no previous header and this is just "out there"?
- # Ignore it!
- next;
}
}
+ else {
+ # Ok, there's a header here, let's go ahead and add it in.
+ if ($header) {
+ # Yes, the /s is needed to match \n too.
+ my ($key, $value) = split (/:\s*(?=.)/s, $header, 2);
- # Ok, there's a header here, let's go ahead and add it in.
- if ($header) {
- # Yes, the /s is needed to match \n too.
- my ($key, $value) = split (/:\s*(?=.)/s, $header, 2);
+ # If it's not a valid header (aka: not in the form "foo: bar"), skip it.
+ if (defined $value) {
+ # limit the length of the pairs we store
+ if (length($key) > MAX_HEADER_KEY_LENGTH) {
+ $key = substr($key, 0, MAX_HEADER_KEY_LENGTH);
+ $self->{'truncated_header'} = 1;
+ }
+ if (length($value) > MAX_HEADER_VALUE_LENGTH) {
+ $value = substr($value, 0, MAX_HEADER_VALUE_LENGTH);
+ $self->{'truncated_header'} = 1;
+ }
+ $self->header($key, $value);
+ }
+ }
- # If it's not a valid header (aka: not in the form "foo: bar"), skip it.
- if (defined $value) {
- # limit the length of the pairs we store
- if (length($key) > MAX_HEADER_KEY_LENGTH) {
- $key = substr($key, 0, MAX_HEADER_KEY_LENGTH);
- $self->{'truncated_header'} = 1;
- }
- if (length($value) > MAX_HEADER_VALUE_LENGTH) {
- $value = substr($value, 0, MAX_HEADER_VALUE_LENGTH);
- $self->{'truncated_header'} = 1;
- }
- $self->header($key, $value);
+ # not a continuation...
+ $header = $last;
+ }
- # If we're currently dealing with a content-type header, and there's a
- # boundary defined, use it. Since there could be multiple
- # content-type headers in a message, the last one will be the one we
- # should use, so just keep updating as they come in.
- if (lc $key eq 'content-type') {
- my($type,$temp_boundary) = Mail::SpamAssassin::Util::parse_content_type($value);
- $boundary = $temp_boundary if ($type =~ /^multipart/ && defined $temp_boundary);
- }
+ if ($header) {
+ if ($header =~ /^\r?$/) {
+ last;
+ }
+ else {
+ # Check for missing head/body separator
+ # RFC 2822, s2.2:
+ # A field name MUST be composed of printable US-ASCII characters
+ # (i.e., characters that have values between 33 (041) and 126 (176), inclusive),
+ # except colon (072).
+ # FOR THIS NEXT PART: list off the valid REs for what can be next:
+ # Header, header continuation, blank line
+ if (!@message || $message[0] !~ /^(?:[\041-\071\073-\176]+:|[ \t]|\r?$)/ || $message[0] =~ /^--/) {
+ # No body or no separator before mime boundary is invalid
+ $self->{'missing_head_body_separator'} = 1;
+
+ # we *have* to go back through again to make sure we catch the last
+ # header, so fake a separator and loop again.
+ unshift(@message, "\n");
+ }
}
}
-
- # not a continuation...
- $header = $last;
-
- # Ok, we found the header/body blank line ...
- last if ($last =~ /^\r?$/m);
-
- # Alternately, if a multipart mime boundary is found in the header area,
- # aka it's malformed, exit out as well and treat it as part of the body.
- last if (defined $boundary && @message && $message[0] =~ /^--\Q$boundary\E(?:--|\s*$)/);
}
# Store the pristine body for later -- store as a copy since @message