diff options
Diffstat (limited to 'imap/src/c-client/rfc822.c')
-rw-r--r-- | imap/src/c-client/rfc822.c | 69 |
1 files changed, 39 insertions, 30 deletions
diff --git a/imap/src/c-client/rfc822.c b/imap/src/c-client/rfc822.c index d9239646..03e92ca3 100644 --- a/imap/src/c-client/rfc822.c +++ b/imap/src/c-client/rfc822.c @@ -1,13 +1,5 @@ /* ======================================================================== - * Copyright 1988-2008 University of Washington - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * + * Copyright 2008-2010 Mark Crispin * ======================================================================== */ @@ -15,13 +7,19 @@ * Program: RFC 2822 and MIME routines * * Author: Mark Crispin - * UW Technology - * University of Washington - * Seattle, WA 98195 - * Internet: MRC@Washington.EDU * * Date: 27 July 1988 - * Last Edited: 14 May 2008 + * Last Edited: 30 September 2010 + * + * Previous versions of this file were: + * + * Copyright 1988-2008 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 * * This original version of this file is * Copyright 1988 Stanford University @@ -284,17 +282,26 @@ void rfc822_parse_content (BODY *body,STRING *bs,char *h,unsigned long depth, } if (!body->subtype) /* default subtype if still unknown */ body->subtype = cpystr (rfc822_default_subtype (body->type)); - /* note offset and sizes */ - body->contents.offset = GETPOS (bs); - /* note internal body size in all cases */ - body->size.bytes = body->contents.text.size = i = SIZE (bs); - if (!(flags & DR_CRLF)) body->size.bytes = strcrlflen (bs); + /* calculate offset */ + if (bs->size >= (body->contents.offset = GETPOS (bs))) { + body->contents.text.size = i = SIZE (bs); + body->size.bytes = (flags & DR_CRLF) ? i : strcrlflen (bs); + } + else { /* paranoia code */ +#if 0 + fatal("rfc822_parse_content botch"); +#endif + body->size.bytes = body->contents.text.size = i = 0; + body->contents.offset = bs->size; + SETPOS(bs,bs->size); + } + switch (body->type) { /* see if anything else special to do */ case TYPETEXT: /* text content */ if (!body->parameter) { /* no parameters set */ body->parameter = mail_newbody_parameter (); body->parameter->attribute = cpystr ("CHARSET"); - while (i--) { /* count lines and guess charset */ + while (i && i--) { /* count lines and guess charset */ c = SNX (bs); /* get current character */ /* charset still unknown? */ if (!body->parameter->value) { @@ -319,7 +326,7 @@ void rfc822_parse_content (BODY *body,STRING *bs,char *h,unsigned long depth, } } /* just count lines */ - else while (i--) if ((SNX (bs)) == '\n') body->size.lines++; + else while (i && i--) if ((SNX (bs)) == '\n') body->size.lines++; break; case TYPEMESSAGE: /* encapsulated message */ @@ -363,6 +370,7 @@ void rfc822_parse_content (BODY *body,STRING *bs,char *h,unsigned long depth, /* count number of lines */ while (i--) if (SNX (bs) == '\n') body->size.lines++; break; + case TYPEMULTIPART: /* multiple parts */ switch (body->encoding) { /* make sure valid encoding */ case ENC7BIT: /* these are valid nested encodings */ @@ -380,7 +388,6 @@ void rfc822_parse_content (BODY *body,STRING *bs,char *h,unsigned long depth, if (!s1) s1 = "-"; /* yucky default */ j = strlen (s1) + 2; /* length of cookie and header */ c = '\012'; /* initially at beginning of line */ - while (i > j) { /* examine data */ if (m = GETPOS (bs)) m--; /* get position in front of character */ switch (c) { /* examine each line */ @@ -405,6 +412,7 @@ void rfc822_parse_content (BODY *body,STRING *bs,char *h,unsigned long depth, } break; } + /* swallow trailing whitespace */ while ((c == ' ') || (c == '\t')) c = ((i && i--) ? (SNX (bs)) : '\012'); @@ -478,7 +486,6 @@ void rfc822_parse_content (BODY *body,STRING *bs,char *h,unsigned long depth, /* end of data ties off the header */ if (!i || !--i) s1[j++] = c = '\0'; } - /* find header item type */ if (((s1[0] == 'C') || (s1[0] == 'c')) && ((s1[1] == 'O') || (s1[1] == 'o')) && @@ -494,6 +501,7 @@ void rfc822_parse_content (BODY *body,STRING *bs,char *h,unsigned long depth, rfc822_parse_content_header (&part->body,ucase (s1+8),s); } } + /* skip header trailing (CR)LF */ if (i && (CHR (bs) =='\015')) {i--; c1 = SNX (bs);} if (i && (CHR (bs) =='\012')) {i--; c1 = SNX (bs);} @@ -1061,7 +1069,7 @@ ADDRESS *rfc822_parse_addrspec (char *string,char **ret,char *defaulthost) else if (!(adr->host = rfc822_parse_domain (++end,&end))) adr->host = cpystr (errhst); /* default host if missing */ - if (!adr->host) adr->host = cpystr (defaulthost); + if (!adr->host) adr->host = cpystr (defaulthost ? defaulthost : "@"); /* try person name in comments if missing */ if (end && !(adr->personal && *adr->personal)) { while (*end == ' ') ++end; /* see if we can find a person name here */ @@ -1380,7 +1388,7 @@ static long rfc822_output_data (RFC822BUFFER *buf,char *string,long len) } /* soutr buffer now if full */ if ((len || (buf->cur == buf->end)) && !rfc822_output_flush (buf)) - return NIL; + return NIL; } return LONGT; } @@ -2064,8 +2072,12 @@ unsigned char *rfc822_qprint (unsigned char *src,unsigned long srcl, t = d; /* accept any leading spaces */ break; default: /* two hex digits then */ - if (!(isxdigit (c) && (((unsigned long) (s - src)) < srcl) && - (e = *s++) && isxdigit (e))) { + if (isxdigit (c) && (((unsigned long) (s - src)) < srcl) && + isxdigit(*s)) { + e = *s++; /* eat second hex digit now */ + *d++ = hex2byte (c,e);/* merge the two hex digits */ + } + else { /* This indicates bad MIME. One way that it can be caused is if a single-section message was QUOTED-PRINTABLE encoded and then something (e.g. a mailing list processor) appended text. The @@ -2081,10 +2093,7 @@ unsigned char *rfc822_qprint (unsigned char *src,unsigned long srcl, } *d++ = '='; /* treat = as ordinary character */ *d++ = c; /* and the character following */ - t = d; /* note point of non-space */ - break; } - *d++ = hex2byte (c,e); /* merge the two hex digits */ t = d; /* note point of non-space */ break; } |