--- libaitwww/src/mime.c 2012/03/08 23:40:21 1.1 +++ libaitwww/src/mime.c 2013/01/17 14:52:44 1.4.6.1 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: mime.c,v 1.1 2012/03/08 23:40:21 misho Exp $ +* $Id: mime.c,v 1.4.6.1 2013/01/17 14:52:44 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -12,7 +12,7 @@ terms: All of the documentation and software included in the ELWIX and AITNET Releases is copyrighted by ELWIX - Sofia/Bulgaria -Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 by Michael Pounov . All rights reserved. Redistribution and use in source and binary forms, with or without @@ -45,7 +45,6 @@ SUCH DAMAGE. */ #include "global.h" #include "mime.h" -#include "tools.h" static int decode_quoted(char *, int, char *); @@ -69,9 +68,9 @@ bd_begin(const char *str) char *s; int len = strlen(str) + 6; - s = malloc(len + 1); + s = e_malloc(len + 1); if (!s) { - LOGERR; + www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); return NULL; } else { snprintf(s, len + 1, "\r\n--%s\r\n", str); @@ -87,9 +86,9 @@ bd_end(const char *str) char *s; int len = strlen(str) + 8; - s = malloc(len + 1); + s = e_malloc(len + 1); if (!s) { - LOGERR; + www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); return NULL; } else { snprintf(s, len + 1, "\r\n--%s--\r\n", str); @@ -151,33 +150,33 @@ freeHeader(struct tagMIME * __restrict m) struct tagCGI *c; while ((c = SLIST_FIRST(&m->mime_header))) { - if (c->cgi_name) - free(c->cgi_name); - if (c->cgi_value) - free(c->cgi_value); + ait_freeVar(&c->cgi_name); + ait_freeVar(&c->cgi_value); + SLIST_REMOVE_HEAD(&m->mime_header, cgi_node); - free(c); + e_free(c); } } -static char * +static ait_val_t * hdrValue(const char *str, size_t len, const char **end) { const char *e, *crlf = NULL; char *tmp, *s = NULL; int off = 0; + ait_val_t *ret = NULL; e = str + len; while (str < e) { - if ((crlf = findtextpos(str, e - str, CRLF, strlen(CRLF)))) { - www_SetErr(EBADMSG, "Bad MIME format message"); + if (!(crlf = findtextpos(str, e - str, CRLF, strlen(CRLF)))) { + www_SetErr(EFAULT, "Bad header format of MIME part"); return NULL; } - tmp = realloc(s, crlf - str + off + 1); + tmp = e_realloc(s, crlf - str + off + 1); if (!tmp) { - LOGERR; - free(s); + www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); + e_free(s); return NULL; } else s = tmp; @@ -195,7 +194,12 @@ hdrValue(const char *str, size_t len, const char **end } *end = crlf + strlen(CRLF); - return s; + ret = ait_makeVar(string, s); + if (!ret) + www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); + e_free(s); + + return ret; } static inline int @@ -328,7 +332,7 @@ mime_parseMultiPart(const char *str, size_t len, const mime_t *mime = NULL; struct iovec bd[2]; struct tagMIME *m, *old = NULL; - const char *next; + const char *next = NULL; if (!str | !bdtag) { www_SetErr(EINVAL, "String or boundary tag is NULL"); @@ -336,9 +340,9 @@ mime_parseMultiPart(const char *str, size_t len, const } /* init MIME */ - mime = malloc(sizeof(mime_t)); + mime = e_malloc(sizeof(mime_t)); if (!mime) { - LOGERR; + www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); return NULL; } else { memset(mime, 0, sizeof(mime_t)); @@ -348,35 +352,37 @@ mime_parseMultiPart(const char *str, size_t len, const /* prepare boundary format */ bd[0].iov_base = bd_begin(bdtag); if (!bd[0].iov_base) { - free(mime); + e_free(mime); return NULL; } else bd[0].iov_len = strlen(bd[0].iov_base); bd[1].iov_base = bd_end(bdtag); if (!bd[1].iov_base) { - free(bd[0].iov_base); - free(mime); + e_free(bd[0].iov_base); + e_free(mime); return NULL; } else bd[1].iov_len = strlen(bd[1].iov_base); + + /* check boundary tag */ if (memcmp(str, strstr(bd[0].iov_base, "--"), strlen(strstr(bd[0].iov_base, "--")))) { - www_SetErr(EBADMSG, "Bad content data, not found boundary tag"); - free(bd[1].iov_base); - free(bd[0].iov_base); - free(mime); + www_SetErr(EFAULT, "Bad content data, not found boundary tag"); + e_free(bd[1].iov_base); + e_free(bd[0].iov_base); + e_free(mime); return NULL; } else { str += strlen(strstr(bd[0].iov_base, "--")); len -= strlen(strstr(bd[0].iov_base, "--")); } - while (42) { - m = malloc(sizeof(struct tagMIME)); + while (len > 0) { + m = e_malloc(sizeof(struct tagMIME)); if (!m) { - LOGERR; + www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); mime_close(&mime); - free(bd[1].iov_base); - free(bd[0].iov_base); + e_free(bd[1].iov_base); + e_free(bd[0].iov_base); return NULL; } else { memset(m, 0, sizeof(struct tagMIME)); @@ -389,8 +395,8 @@ mime_parseMultiPart(const char *str, size_t len, const /* parse message between tags */ if (mime_readPart(m, str, next - str)) { mime_close(&mime); - free(bd[1].iov_base); - free(bd[0].iov_base); + e_free(bd[1].iov_base); + e_free(bd[0].iov_base); return NULL; } @@ -413,8 +419,14 @@ mime_parseMultiPart(const char *str, size_t len, const } str += bd[0].iov_len; + /* LLVM static code analyzer said for this - unusable + * len -= bd[0].iov_len; + */ + e_free(bd[1].iov_base); + e_free(bd[0].iov_base); + if (end) *end = str; return mime; @@ -424,11 +436,11 @@ static inline void freeMIME(struct tagMIME * __restrict m) { if (m->mime_body.iov_base) - free(m->mime_body.iov_base); + e_free(m->mime_body.iov_base); if (m->mime_prolog.iov_base) - free(m->mime_prolog.iov_base); + e_free(m->mime_prolog.iov_base); if (m->mime_epilog.iov_base) - free(m->mime_epilog.iov_base); + e_free(m->mime_epilog.iov_base); freeHeader(m); mime_close(&m->mime_attach); @@ -451,10 +463,10 @@ mime_close(mime_t ** __restrict mime) while ((m = SLIST_FIRST(*mime))) { SLIST_REMOVE_HEAD(*mime, mime_node); freeMIME(m); - free(m); + e_free(m); } - free(*mime); + e_free(*mime); *mime = NULL; } @@ -488,30 +500,34 @@ mime_parseHeader(struct tagMIME * __restrict m, const colon = memchr(str, ':', e - str); eoh = findtextpos(str, e - str, CRLF, strlen(CRLF)); if (!colon || !eoh || colon > eoh) { - www_SetErr(EBADMSG, "Bad MIME format message"); + www_SetErr(EFAULT, "Bad MIME format message"); freeHeader(m); return -1; } - c = malloc(sizeof(struct tagCGI)); + c = e_malloc(sizeof(struct tagCGI)); if (!c) { - LOGERR; + www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); freeHeader(m); return -1; } /* get name */ - c->cgi_name = malloc(colon - str + 1); + c->cgi_name = ait_allocVar(); if (!c->cgi_name) { - LOGERR; - free(c); + www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); + e_free(c); freeHeader(m); return -1; - } else { - memcpy(c->cgi_name, str, colon - str); - c->cgi_name[colon - str] = 0; - } + } else + AIT_SET_STRLCPY(c->cgi_name, str, colon - str + 1); /* get value */ c->cgi_value = hdrValue(colon + 1, e - colon - 1, &str); + if (!c->cgi_value) { + free(c->cgi_name); + free(c); + freeHeader(m); + return -1; + } if (!old) SLIST_INSERT_HEAD(&m->mime_header, c, cgi_node); @@ -536,14 +552,12 @@ inline const char * mime_getValue(struct tagMIME * __restrict m, const char *name) { struct tagCGI *c; - const char *v = NULL; SLIST_FOREACH(c, &m->mime_header, cgi_node) - if (!strcmp(c->cgi_name, name)) { - v = c->cgi_value; - break; - } - return v; + if (!strcasecmp(AIT_GET_STR(c->cgi_name), name)) + return AIT_GET_STR(c->cgi_value); + + return NULL; } /* @@ -560,9 +574,10 @@ mime_readPart(struct tagMIME * __restrict m, const cha const char *eoh, *ct, *eb; cgi_t *attr; struct iovec bd; + ait_val_t *v; - if (!m || !str) { - www_SetErr(EINVAL, "Mime part or string is NULL"); + if (!m || !str || (ssize_t) len < 0) { + www_SetErr(EINVAL, "Mime part, string is NULL or length is less 0"); return -1; } @@ -572,26 +587,35 @@ mime_readPart(struct tagMIME * __restrict m, const cha ct = mime_getValue(m, "content-type"); if (!ct || www_cmptype(ct, "multipart")) { /* not multi part, assign like body element */ - m->mime_body.iov_base = malloc(len - (eoh - str) + 1); + m->mime_body.iov_base = e_malloc(len - (eoh - str) + 1); + if (!m->mime_body.iov_base) { + www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); + freeHeader(m); + return -1; + } memcpy(m->mime_body.iov_base, eoh, len - (eoh - str)); ((char*) m->mime_body.iov_base)[len - (eoh - str)] = 0; m->mime_body.iov_len = len - (eoh - str) + 1; } else { /* multi part */ attr = www_parseAttributes(&ct); - if (!attr) + if (!attr) { + freeHeader(m); return -1; - bd.iov_base = bd_begin(www_getAttribute(attr, "boundary")); + } + v = www_getAttribute(attr, "boundary"); + bd.iov_base = bd_begin(AIT_GET_STR(v)); bd.iov_len = strlen(bd.iov_base); eb = findtextpos(eoh, len - (eoh - str), bd.iov_base, bd.iov_len); - free(bd.iov_base); + e_free(bd.iov_base); /* set prolog if exists */ if (eb != eoh) { - m->mime_prolog.iov_base = malloc(eb - eoh + 1); + m->mime_prolog.iov_base = e_malloc(eb - eoh + 1); if (!m->mime_prolog.iov_base) { - LOGERR; + www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); www_freeAttributes(&attr); + freeHeader(m); return -1; } memcpy(m->mime_prolog.iov_base, eoh, eb - eoh); @@ -599,15 +623,17 @@ mime_readPart(struct tagMIME * __restrict m, const cha m->mime_prolog.iov_len = eb - eoh + 1; } + v = www_getAttribute(attr, "boundary"); m->mime_attach = mime_parseMultiPart(eb + 1, len - (eb + 1 - str), - www_getAttribute(attr, "boundary"), &eoh); + AIT_GET_STR(v), &eoh); /* set epilog if exists */ if (eoh - str < len) { - m->mime_epilog.iov_base = malloc(len - (eoh - str) + 1); + m->mime_epilog.iov_base = e_malloc(len - (eoh - str) + 1); if (!m->mime_epilog.iov_base) { - LOGERR; + www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); www_freeAttributes(&attr); + freeHeader(m); return -1; } memcpy(m->mime_epilog.iov_base, str, len - (eoh - str)); @@ -615,9 +641,10 @@ mime_readPart(struct tagMIME * __restrict m, const cha m->mime_epilog.iov_len = len - (eoh - str) + 1; } + + www_freeAttributes(&attr); } - www_freeAttributes(&attr); return 0; } @@ -648,7 +675,7 @@ mime_calcRawSize(struct tagMIME * __restrict m) if (!s) return m->mime_body.iov_len; /* strip whitespaces */ - while (isspace(*s)) + while (isspace((int) *s)) s++; t = strchr(s, ';'); len = t ? strlen(s) : t - s; @@ -699,7 +726,7 @@ mime_getRawData(struct tagMIME * __restrict m, char * } /* strip whitespaces */ - while (isspace(*s)) + while (isspace((int) *s)) s++; t = strchr(s, ';'); len = t ? strlen(s) : t - s;