static void mime_param_free(MIME_PARAM *param);
static int mime_bound_check(char *line, int linelen, char *bound, int blen);
static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret);
-static int strip_eol(char *linebuf, int *plen);
+static int strip_eol(char *linebuf, int *plen, int flags);
static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name);
static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name);
static void mime_hdr_free(MIME_HEADER *hdr);
}
else
{
+ int eolcnt = 0;
if(flags & SMIME_TEXT)
BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0)
{
- eol = strip_eol(linebuf, &len);
+ eol = strip_eol(linebuf, &len, flags);
if (len)
+ {
+ /* Not EOF: write out all CRLF */
+ if (flags & SMIME_ASCIICRLF)
+ {
+ int i;
+ for(i = 0; i < eolcnt; i++)
+ BIO_write(out, "\r\n", 2);
+ eolcnt = 0;
+ }
BIO_write(out, linebuf, len);
- if(eol) BIO_write(out, "\r\n", 2);
+ if(eol)
+ BIO_write(out, "\r\n", 2);
+ }
+ else if (flags & SMIME_ASCIICRLF)
+ eolcnt++;
+ else if(eol)
+ BIO_write(out, "\r\n", 2);
}
}
(void)BIO_flush(out);
first = 1;
parts = sk_BIO_new_null();
*ret = parts;
+ if (*ret == NULL)
+ return 0;
while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
state = mime_bound_check(linebuf, len, bound, blen);
if(state == 1) {
first = 1;
part++;
} else if(state == 2) {
- sk_BIO_push(parts, bpart);
+ if (!sk_BIO_push(parts, bpart))
+ {
+ BIO_free(bpart);
+ return 0;
+ }
return 1;
} else if(part) {
/* Strip CR+LF from linebuf */
- next_eol = strip_eol(linebuf, &len);
+ next_eol = strip_eol(linebuf, &len, 0);
if(first) {
first = 0;
- if(bpart) sk_BIO_push(parts, bpart);
+ if(bpart)
+ if (!sk_BIO_push(parts, bpart))
+ {
+ BIO_free(bpart);
+ return 0;
+ }
bpart = BIO_new(BIO_s_mem());
+ if (bpart == NULL)
+ return 0;
BIO_set_mem_eof_return(bpart, 0);
} else if (eol)
BIO_write(bpart, "\r\n", 2);
BIO_write(bpart, linebuf, len);
}
}
+ if (bpart != NULL)
+ BIO_free(bpart);
return 0;
}
int len, state, save_state = 0;
headers = sk_MIME_HEADER_new(mime_hdr_cmp);
+ if (!headers)
+ return NULL;
while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
/* If whitespace at line start then continuation line */
if(mhdr && isspace((unsigned char)linebuf[0])) state = MIME_NAME;
static MIME_HEADER *mime_hdr_new(char *name, char *value)
{
- MIME_HEADER *mhdr;
- char *tmpname, *tmpval, *p;
+ MIME_HEADER *mhdr = NULL;
+ char *tmpname = NULL, *tmpval = NULL, *p;
int c;
if(name) {
if(!(tmpname = BUF_strdup(name))) return NULL;
*p = c;
}
}
- } else tmpname = NULL;
+ }
if(value) {
- if(!(tmpval = BUF_strdup(value))) return NULL;
+ if(!(tmpval = BUF_strdup(value)))
+ goto err;
for(p = tmpval ; *p; p++) {
c = (unsigned char)*p;
if(isupper(c)) {
*p = c;
}
}
- } else tmpval = NULL;
+ }
mhdr = (MIME_HEADER *) OPENSSL_malloc(sizeof(MIME_HEADER));
- if(!mhdr) return NULL;
+ if(!mhdr) goto err;
mhdr->name = tmpname;
mhdr->value = tmpval;
- if(!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp))) return NULL;
+ if(!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp)))
+ goto err;
return mhdr;
+
+ err:
+ if (tmpname != NULL)
+ OPENSSL_free(tmpname);
+ if (tmpval != NULL)
+ OPENSSL_free(tmpval);
+ if (mhdr != NULL)
+ OPENSSL_free(mhdr);
+ return NULL;
}
static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
{
- char *tmpname, *tmpval, *p;
+ char *tmpname=NULL, *tmpval=NULL, *p;
int c;
- MIME_PARAM *mparam;
+ MIME_PARAM *mparam=NULL;
if(name) {
tmpname = BUF_strdup(name);
- if(!tmpname) return 0;
+ if(!tmpname) goto err;
for(p = tmpname ; *p; p++) {
c = (unsigned char)*p;
if(isupper(c)) {
*p = c;
}
}
- } else tmpname = NULL;
+ }
if(value) {
tmpval = BUF_strdup(value);
- if(!tmpval) return 0;
- } else tmpval = NULL;
+ if(!tmpval) goto err;
+ }
/* Parameter values are case sensitive so leave as is */
mparam = (MIME_PARAM *) OPENSSL_malloc(sizeof(MIME_PARAM));
- if(!mparam) return 0;
+ if(!mparam) goto err;
mparam->param_name = tmpname;
mparam->param_value = tmpval;
- sk_MIME_PARAM_push(mhdr->params, mparam);
+ if (!sk_MIME_PARAM_push(mhdr->params, mparam))
+ goto err;
return 1;
+err:
+ if (tmpname != NULL)
+ OPENSSL_free(tmpname);
+ if (tmpval != NULL)
+ OPENSSL_free(tmpval);
+ if (mparam != NULL)
+ OPENSSL_free(mparam);
+ return 0;
}
static int mime_hdr_cmp(const MIME_HEADER * const *a,
const MIME_HEADER * const *b)
{
- if ((*a)->name == NULL || (*b)->name == NULL)
- return (*a)->name - (*b)->name < 0 ? -1 :
- (*a)->name - (*b)->name > 0 ? 1 : 0;
+ if (!(*a)->name || !(*b)->name)
+ return !!(*a)->name - !!(*b)->name;
return(strcmp((*a)->name, (*b)->name));
}
static int mime_param_cmp(const MIME_PARAM * const *a,
const MIME_PARAM * const *b)
{
+ if (!(*a)->param_name || !(*b)->param_name)
+ return !!(*a)->param_name - !!(*b)->param_name;
return(strcmp((*a)->param_name, (*b)->param_name));
}
return 0;
}
-static int strip_eol(char *linebuf, int *plen)
+static int strip_eol(char *linebuf, int *plen, int flags)
{
int len = *plen;
char *p, c;
c = *p;
if (c == '\n')
is_eol = 1;
+ else if (is_eol && flags & SMIME_ASCIICRLF && c < 33)
+ continue;
else if (c != '\r')
break;
}