summaryrefslogtreecommitdiff
path: root/imap/src/c-client/rfc822.c
diff options
context:
space:
mode:
Diffstat (limited to 'imap/src/c-client/rfc822.c')
-rw-r--r--imap/src/c-client/rfc822.c69
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;
}